Java 中是否存在一种反射类型,它只是类中字段的枚举?
你问预编译?!在这里,编译器添加枚举,然后处理代码。因此,作者可以在编译之前以枚举的形式引用这些字段。是的,这看起来像是一种特殊情况,一次性的,但映射/POJO/ORM 空间的好处将是巨大的。
虽然不是我正在寻找的解决方案,Lombok可以有这个,但是它没有(请参阅@FieldNameConstants)
这些字段就位于类文件中,因此我正在绞尽脑汁地思考是否需要一种“动态反射方法”来简单地能够“引用类的字段”作为枚举。是的,“预编译”看起来很奇怪。 (意味着编译器在内部执行两步过程)
enum Fields { ... }
寻找一个集合
的子集,并从集合中过滤掉一些字段(参见示例) ...并且可能调用一些 getter/setter,尽管
非经典,例如
o.setString(MyClass.Fields.AFIELD, value)
再次听我说……虽然从很多角度来看都有点呃,但从 ORM 的角度来看,就像……
需要 7 种类型的 setter。当 ORM 或 http params-to-Java 占代码库的 80% 时,“理论与实践”,更残酷的现实获胜。
任何编译器标志
可以启用此功能?public class NiceClass {
//* NOTE this is not real java code today - don't copy and paste expecting it to work! */
static {
Set<NiceClass.class.field> allMyFields = NiceClass.class.fieldz.public();
Set<NiceClass.class.field> allMyLocalPublicFields = NiceClass.class.fieldz.local.public();
Set<NiceClass.class.field> allMyLocalPrivateAndLocalProtectedFields = { Sets.union(
NiceClass.class.fieldz.local.private(),
NiceClass.class.fieldz.local.protected())}
Set<NiceClass.class.field> specificFields = { Set.of(NiceClass.class.fields.ONE,
NiceClass.class.fields.THREE,
NiceClass.class.fields.FIVE )}
Set<NiceClass.class.field> allFieldsWithoutLoggerByFieldName = {
NiceClass.class.fieldz.all().stream().filter(s-> s.name != "logger" ).collect(Collectors.toSet()) }
Set<NiceClass.class.field> allFieldsWithoutLoggerByType = {
NiceClass.class.fieldz.all().stream().filter(s-> s.type != Logger.class ).collect(Collectors.toSet())
}
Set<NiceClass.class.field> allNonTransientFields = {
NiceClass.class.fieldz.all().stream().filter(s-> s.modifier != Modifier.transient ).collect(Collectors.toSet())
}
Set<NiceClass.class.field> holyGrailMySerialization = {
allFieldsWithoutLoggerByType.stream().filter(s-> s.access != private &&
! Modifiers.contains(Modifier.transient) &&
! Modifiers.contains(Modifier.volatile) &&
s.type != MyCredentials.class )
.collect(Collectors.toSet())
}
Set<NiceClass.class.field> holyGrailMySerialization = {
holdGrailMySerialization.stream().filter(s-> ! s.annotations.contains(PrivateStuff.class) )
.collect(Collectors.toSet())
}
//and if you give the mouse a cookie...why shouldn't these be easy to "enable"?
public void set(Object.FieldInterface fieldEnum, Object value); //(casting in impl)
//and typesafe...
NiceClass.class.fieldz.stream().filter(
s->s.setterEnabled)
.map(s->s.type)
.collect(Collectors.toSet()).foreach(s->{
<modifiers> void set<s.type>(fieldEnum, value);
}
})
//bonus to figure out how to reduce that param to what's *statically enabled*...
//I know this is wonky looking syntax ( a Set of types allowed in a generic? )
<modifiers> void set<s.type>(Object.FieldInterface<!!Set.contains(NiceClass.class.fieldz.enabled)>) fieldEnum, value);
//Anyways, the possibilties seem endless having this lightweight reflection...
}
原来有一个Javac Plugin API
也许有一天 javac 会将这种元数据添加到 .class 文件中?在那之前,这就足够了。