【问题标题】:How to create synthetic fields in java?如何在java中创建合成字段?
【发布时间】:2010-07-21 10:09:34
【问题描述】:
  1. 如何在 Java 中创建合成字段?

  2. java 中的合成字段只能在运行时创建吗? 如果没有:在编译时是否有符合标准的方法(不更改类文件中的某些字节)

【问题讨论】:

  • 为什么要手动创建合成字段?这有点违反它的规范,因为它说“这是编译器为启用某些特定行为所做的事情”。您想要手动执行的任何操作都应该对外部可见。

标签: java reflection


【解决方案1】:

当语言的“奇怪”需要它们时,它们由编译器创建。一个简单的例子是使用内部类:

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

【讨论】:

    【解决方案2】:

    是的,它是可行的,它被称为加载时编织。本质上,您将需要定义自己的 ClassLoader,它将逐个决定是否修改即将加载的类文件;这意味着您将需要检查正在加载的二进制类,可能对其进行修改,然后将其传递给 JVM 以进行定义/解析。这有点麻烦、复杂,并且容易出现 ClassCastExceptions(在 2 个不同的类加载器中定义的同一个类会给出 2 个不兼容赋值的不同类)。

    请注意,编织允许您做更多事情:您可以添加新方法、接口、字段、修改现有类的代码等等。

    已经有一些工具可以为您提供帮助 - 例如,将 AspectJ 视为一种全面的语言修改,或者像 BCEL 或 javassist 之类的允许您编写此类编织工具的工具。

    【讨论】:

      【解决方案3】:

      如何在 Java 中创建合成字段?

      synthetic 字段由 Java 编译器自动创建,在某些特定情况下。

      例子:

      java中的合成字段只能在运行时创建吗?如果没有:在编译时是否有符合标准的方法(不更改类文件中的某些字节)

      synthetic 是由 Java 编译器在编译时生成的。 .class 文件已包含 ACC_SYNTHETIC 标志。虽然我们总是可以在运行时生成 Java 字段。

      更多信息

      • 这个article 详细描述了ACC_SYNTHETIC 标志
      • 这个link 列出了JDK 中的所有synthetic 字段

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-15
        • 1970-01-01
        • 1970-01-01
        • 2016-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多