繁体   English   中英

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

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

有没有一种方法可以在不使用反射的情况下访问类中的特定Field

考虑此类:

class MyType {
    public int theNumber;
}

我想访问theNumberjava.lang.reflect.Field

这可以肯定地工作:

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

但是,我想对字段名称进行编译检查,因此理想情况下是这样的(但是我的示例当然不会编译):

Field f = MyType.class::theNumber;

这是可能的还是我可以利用编译器功能?

有趣的问题。 不,如果不使用java.lang.reflect ,是无法做到这一点的,但是鉴于class的内置class伪属性,我可以理解为什么会这样。

您可以使用注释处理器扩展Java编译器。 该处理器是在编译过程中扫描源代码的一种方式。 它们是随注释一起引入的,但是它们不仅可以扫描注释,而且还可以扫描整个源代码。

使用扫描的源代码,您可以生成访问器类,以编译任何类。 这样您可以消除反射。

如果只想在IDE中编写代码时出错,则可以使用javax.annotation.processing.ProcessingEnvironment.getMessager()。printMessage()(另请参见javax.tools.DiagnosticListener)来生成IDE可以显示的错误。 。

因此,基本思想是:

  1. 编写注释处理器,以扫描您要反映的源代码
  2. 通过javax.lang.model.element.ElementVisitor提取您想要访问的字段

如果要生成类型,请保存对字段的访问:

3.1。 生成将访问此源代码的源

如果您想确保对字段的反射调用有效:

3.2。 通过ProcessingEnvironment.getMessager()。printMessage()引发错误

当然,您必须编写代码以检查反射调用或生成访问器。

而且,您想获取的信息必须可从源代码中提取出来,因为所有的魔术都发生在编译期间而不是在运行时

JPA2元模型(用于类型安全查询“按条件”)具有类似的概念。

MyType_.theNumber

由额外的“预处理器”实现。 您可以在这方面进行调查。

不,不是...但是您可以通过接口和闭包来实现

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