Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以生成类的内部类以使用注释处理器进行编译?_Java_Android_Annotations_Annotation Processing - Fatal编程技术网

Java 是否可以生成类的内部类以使用注释处理器进行编译?

Java 是否可以生成类的内部类以使用注释处理器进行编译?,java,android,annotations,annotation-processing,Java,Android,Annotations,Annotation Processing,我想知道是否有可能通过注释处理器生成一个类,该类将是要编译的类的内部类 例如,在编译classA时,生成classA$Foo。我想知道是否有一个技巧可以使用或不。我觉得有可能生成一些源代码,这些源代码将被编译成与内部类相同的字节码。而且,在编译/运行时,JVM将把它作为一个内部类,并允许访问外部类的私有字段 这个问题背后的想法不是一个noobie问题,尽管它看起来或多或少有点技术性,但它能够为带注释的字段(如Dagger、ButterKnife等)使用私有可见性修饰符。私有修饰符允许更容易地检测

我想知道是否有可能通过注释处理器生成一个类,该类将是要编译的类的内部类

例如,在编译class
A
时,生成class
A$Foo
。我想知道是否有一个技巧可以使用或不。我觉得有可能生成一些源代码,这些源代码将被编译成与内部类相同的字节码。而且,在编译/运行时,JVM将把它作为一个内部类,并允许访问外部类的私有字段

这个问题背后的想法不是一个noobie问题,尽管它看起来或多或少有点技术性,但它能够为带注释的字段(如Dagger、ButterKnife等)使用私有可见性修饰符。私有修饰符允许更容易地检测未使用的字段,而包私有保护将其隐藏


或者有什么解决办法,有什么方法可以充分利用这两个词吗?

私有可见性实际上只是对编译器的一个提示。在运行时访问这些字段完全没有问题(就像我在小型依赖项注入器中所做的那样:)

android上的非静态内部类通常是一个坏主意,因为它曾经有性能损失


在编译时,您可以使用诸如xdoclet之类的源代码生成工具(虽然它在技术上几年前就过时了,但偶尔也会使用),并在编译之前提前生成所需的所有源代码

考虑到您的用例,没有

内部类是一个普通的Java类,位于不同的.class文件中。编译时,将向内部类构造函数添加一个隐藏构造函数param。通过在外部类中添加隐藏的访问器方法,可以访问外部类中的私有字段。所有这些都发生在编译时


JVM与此无关。如果生成的类“看起来像另一个类的内部类”,则无法访问外部类字段。

否。不能修改现有源文件,只需创建新的源文件即可。但我总是根据该方案命名生成的类,例如
SomeInterface$Impl
,以表明生成的类属于
SomeInterface
。但我确切地知道你的意思,我经常使用注释处理,并在我的库中大量使用它,我只是希望这是可能的。。。。我通常倾向于生成私有的最终实现类,然后生成一个公共工厂类,该类使用私有实现类创建这些接口的实例。您可以称之为一种变通方法。在您链接到的库中,您正在使用反射来执行注入。在大多数情况下,这正是您在使用注释处理和代码生成时想要避免的。生成的代码必须是有效代码,有效代码不能访问私有字段。私有可见性不仅仅是“对编译器的提示”。在默认情况下,您可以使用反射访问私有字段,但如果您的代码在具有其他安全管理器的上下文中运行,则可以禁用此选项。在这种情况下,
Field.setAccessible
抛出
SecurityException
。这就是我对该限制的一般想法。实际上,添加内部和外部类的几个Java-C转储将有助于考虑这个答案规范。而且,这仅适用于JavaC编译器,ECJ AFAIK有不同的机制来表示外部类和内部类之间的链接。