简体   繁体   English

访问类的字段而不使用反射?

[英]Access to class' Fields without using reflection?

Is there a way to access a specific Field on a class without using reflection? 有没有一种方法可以在不使用反射的情况下访问类中的特定Field

Consider this class: 考虑此类:

class MyType {
    public int theNumber;
}

Where I would like to get access to theNumber 's java.lang.reflect.Field . 我想访问theNumberjava.lang.reflect.Field

This works for sure: 这可以肯定地工作:

Field f = MyType.class.getDeclaredField("theNumber");

However, I would like compile check on the field name, so ideally something like this instead (but of course my example doesn't compile): 但是,我想对字段名称进行编译检查,因此理想情况下是这样的(但是我的示例当然不会编译):

Field f = MyType.class::theNumber;

Is this possible or am I way of wrt the compiler abilities? 这是可能的还是我可以利用编译器功能?

Interesting question. 有趣的问题。 No, there's no way to do that without using java.lang.reflect , but given the built-in class pseudo-property on classes, I can see why you'd ask. 不,如果不使用java.lang.reflect ,是无法做到这一点的,但是鉴于class的内置class伪属性,我可以理解为什么会这样。

You can extend the java compiler with annotation processors. 您可以使用注释处理器扩展Java编译器。 This processors are a way to scan your source code during compile. 该处理器是在编译过程中扫描源代码的一种方式。 They were introduced with Annotations but they are able to scan the whole source code not only annotations. 它们是随注释一起引入的,但是它们不仅可以扫描注释,而且还可以扫描整个源代码。

With the scanned Source-Code you can generate accessor classes to any class you compile. 使用扫描的源代码,您可以生成访问器类,以编译任何类。 This way you can eliminate reflection. 这样您可以消除反射。

If you only want to get errors while you write code in your IDE you can make use of javax.annotation.processing.ProcessingEnvironment.getMessager().printMessage() (see also javax.tools.DiagnosticListener) to generate Errors the IDE can show. 如果只想在IDE中编写代码时出错,则可以使用javax.annotation.processing.ProcessingEnvironment.getMessager()。printMessage()(另请参见javax.tools.DiagnosticListener)来生成IDE可以显示的错误。 。

So the basic Idea is: 因此,基本思想是:

  1. write an annotation processor which scans the source code you want to reflect 编写注释处理器,以扫描您要反映的源代码
  2. extract the field you want to have access to via javax.lang.model.element.ElementVisitor 通过javax.lang.model.element.ElementVisitor提取您想要访问的字段

In case you want to generate type save access to Field: 如果要生成类型,请保存对字段的访问:

3.1. 3.1。 generate source that will access this source code 生成将访问此源代码的源

In case you want to ensure, that a reflective call to a field is valid: 如果您想确保对字段的反射调用有效:

3.2. 3.2。 raise an Error via ProcessingEnvironment.getMessager().printMessage() 通过ProcessingEnvironment.getMessager()。printMessage()引发错误

Of course you have to write the code for checking reflective calls or generating the accessors. 当然,您必须编写代码以检查反射调用或生成访问器。

And the information you want to get must be extractable from the sourcecode since all the magic happens during the compile and not at runtime 而且,您想获取的信息必须可从源代码中提取出来,因为所有的魔术都发生在编译期间而不是在运行时

JPA2 Metamodel (used in typesafe queries "by criteria") has similar concept. JPA2元模型(用于类型安全查询“按条件”)具有类似的概念。

MyType_.theNumber

Is implemented by extra "pre-processors". 由额外的“预处理器”实现。 You can investigate in this area. 您可以在这方面进行调查。

No, It's not... but you could achieve it with an interface and a closure 不,不是...但是您可以通过接口和闭包来实现

public interface Getter<T, V> {
    V get(T object);
}

public static Getter<MyType, Integer> theNumberGetter = (MyType myType) -> { myType.theNumber };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM