当前位置: 首页 > 知识库问答 >
问题:

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

阎丰羽
2023-03-14

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

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

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

共有2个答案

呼延德华
2023-03-14

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

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

“某些面向对象编程语言在运行时确定对象类型的能力。”

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

我想在编译阶段使用它。

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

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

隆向晨
2023-03-14

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

对于编译时解决方案的请求:有一个解决方案,但您需要实现自己的构建器。

因为实现和包含您自己的构建器可能需要大量工作,但收效甚微,所以这里有一个简单得多的答案:类初始化。

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_LAZY_INIT;
    static {
        ARRAYLIST_CLASS_NAME_LAZY_INIT = 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_LAZY_INIT);

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

}

静态初始化将在类初始化中花费(非常少的)时间。这是运行时的一部分,但是只有当一个类在执行的代码中被引用/元计算时,它才会发生。这种初始化只会进行一次(每个类加载器加载的类),并且被认为是非常快的。

>

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

    您可以编写自己的构建器,并将其包含到构建周期的构建周期中。最好的方法是通过注释“预”处理器。

    第三个选择是编写一个完整的独立应用程序。这意味着你必须实现:

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

    并将其纳入构建周期。这在上面的文章中也有部分描述

  •  类似资料:
    • 问题内容: 我有以下签名的方法: 它读取json字符串,并将其转换为适当类型的对象的列表,例如。整数,字符串等 是否有一种可靠的方法可以通过从参数中推断出参数来将其从方法中删除?例如。有没有办法可以在不丢失功能的情况下将方法签名更改为以下内容? 似乎该解决方案将需要对ParameterizedType进行一些精美的操作。我看了以下内容,但是我使用的方法不正确,或者它们没有达到我的期望: 来自htt

    • 我正在尝试在运行时向类动态添加注释,如以下问题所示:在运行时修改类定义的注释字符串参数 但是,“annotations”字段将返回null。事实上,根据调试器,除了“declaredFields”和“name”之外,类上的所有内容都返回null。我正在使用Java 7。 这是我的代码:

    • 我想在我的主页上显示我的JSON数据,但我有一个问题。当我运行时,出现一条错误消息“以下类型错误被抛出构建FutureBuilder(脏,状态:_FutureBuilderState#d0e99):”和(错误:类型“List”不是类型“Map”的子类型 下面是我的示例JSON片段(注意:这是本地JSON): 以下是我的餐厅档案: 下面是主页代码:

    • 这两个类路径能完全不同吗?

    • 问题内容: 我需要区分以下类型 从。使用,告诉我这是的。如何与区别开来,而没有要检查的有限类型列表? 在新版本的Go中,有没有新的方法可以做到这一点? 问题答案: 一些背景 首先让我们清除一些与类型有关的东西。引用规格:类型: 类型确定一组值和特定于该类型值的操作。类型可以是已 命名的 或未 命名的 。命名类型由(可能是限定的)类型名指定;未命名的类型使用 类型文字 来指定,该类型由现有类型组成一

    • 问题内容: 我使用的枚举中的常量是一个类。我需要在常量上调用一个方法,但无法引入编译时依赖性,并且枚举在运行时并非始终可用(可选安装的一部分)。因此,我想使用反射。 这很容易,但是我以前没有对枚举使用反射。 枚举看起来像这样: 用反射调用常量方法的例子是什么? 问题答案: