Java:运行时反射还是类型自省?

Java: runtime reflection or type introspection?

下面的代码是运行时反射还是类型内省

Class c = java.util.ArrayList.class;
String className = c.getName();

我想在编译阶段使用这个,不想在运行时使用任何资源(包括时间)。它是否使用任何运行时资源?

我会说它既是运行时反射又是类型自省。

请注意,[introspection] 标记将内省定义为:

"A capability of some object-oriented programming languages to determine the type of an object at runtime."

您也可以说您的示例使用(运行时)反射来执行类型自省。


I want to use this in the compilation phase.

可以在编译时在注解处理器中检查类型。但是,我怀疑这样做所涉及的努力是令人望而却步的。您需要能够在两个语句中发现特定模式,然后用其他内容替换这些语句。

(您是否对 class 名称查找进行了基准测试,以了解它实际花费了多少时间?我本以为这只是几纳秒。不够重要。)

两者都是,正如@StephenC 已经正确指出的那样。

针对您对 compile-time 解决方案的请求:有一个解决方案,但您需要为此实施自己的构建器。

首先,一些 standard-Java 实现:

因为实施和包含您自己的构建器可能需要做很多工作而收效甚微,这里有一个更简单的答案:class 初始化。

public class CompileTimeInit {

    // option 1
    static public final String ARRAYLIST_CLASS_NAME = java.util.ArrayList.class.getName();

    // option 2
    static public final String ARRAYLIST_CLASS_NAME_INIT_BLOCK;
    static {
        ARRAYLIST_CLASS_NAME_INIT_BLOCK = java.util.ArrayList.class.getName();
    }

    public static void main(final String[] args) {
        System.out.println("1:\t" + ARRAYLIST_CLASS_NAME);

        System.out.println("2:\t" + ARRAYLIST_CLASS_NAME_INIT_BLOCK);

        // option 3
        final Class c = java.util.ArrayList.class;
        final String className = c.getName();
        System.out.println("3:\t" + className);
    }

}

静态初始化将在 class 初始化中花费(非常少的)时间。这是运行时的一部分,但它只会在执行的某些代码中 class 为 referenced/metnioned 时发生。此初始化只会执行一次(每个 classloader 加载 class)并且被认为非常快。

现在,真正的 compile-time 实现:

  1. 您可以像 Project Lombok 那样实现真正高级的构建器,并集成到 IDE、编译器、构建工具和平台中。查看他们的页面、顶部菜单、“安装”,查看可用的选项。

  2. 您可以编写自己的构建器并将其包含在构建周期的构建周期中。最好的方法是通过 Annotaion "Pre"-Processor.

  3. 第三种选择是编写一个完整的独立应用程序。这意味着您必须实施:

  • 正在打开 .java 个源文件
  • 正在扫描您的界面或注释
  • 用计算出的内容替换代码
  • 正在保存 .java 个源文件
  • 让编译阶段继续

并将其纳入您的构建周期。这在文章 above

中也有部分描述