如何在Java中创建合成字段?
java中的合成字段只能在运行时创建吗? 如果不是:在编译时是否有符合标准的方法(不改变类文件中的某些字节)
答案 0 :(得分:15)
当语言的“奇怪”需要它们时,它们是由编译器创建的。一个简单的例子是使用内部类:
public class Test
{
class Inner
{
}
}
Test.Inner
类将有一个合成字段来表示Test
类的相应实例。
我们可以稍微扩展此代码以显示该字段:
import java.lang.reflect.*;
public class Test
{
public static void main(String[] args)
{
for (Field field : Inner.class.getDeclaredFields())
{
System.out.println(field.getName() + ": " + field.isSynthetic());
}
}
class Inner
{
}
}
使用我的编译器打印:
this$0: true
答案 1 :(得分:4)
是的,它是可行的,它被称为加载时编织。本质上,您需要定义自己的ClassLoader,它将决定是否修改要加载的bout的类文件。这意味着您将需要检查正在加载的二进制类,可能需要对其进行修改,然后将其传递给JVM以进行定义/解析。它有点麻烦,复杂,并且容易出现ClassCastExceptions(在2个不同的类加载器中定义的相同类将提供2个不兼容分配的不同类。)
请注意,编织允许您执行更多操作:您可以添加新方法,接口,字段,修改现有类的代码等。
已经有一些工具可以帮助您 - 例如看看AspectJ是一个全面的语言修改,或者像BCEL或javassist这样的东西,可以让你编写这样的编织工具。
答案 2 :(得分:1)
如何用Java创建合成字段?
synthetic
字段是在某些特定情况下由Java编译器自动创建的。
示例:
帮助处理Java assert
关键字-java.awt.AWTKeyStroke。$assertionsDisabled
帮助处理Java this
关键字-java.util.AbstractList$Itr。this$0
匿名内部类中的字段-java.util.AbstractList$SubList$1。val$index
枚举字段的帮助过程-java.nio.file.attribute.AclEntryFlag。$VALUES
只能在运行时创建Java中的合成字段吗?如果不是这样:编译时是否有符合标准的方法(无需更改类文件中的某些字节)
synthetic
由Java编译器在编译时生成。 .class
文件已经包含ACC_SYNTHETIC
标志。尽管我们总是可以在运行时生成Java字段。