【问题标题】:Reflection API, Class.forName() vs .class反射 API,Class.forName() 与 .class
【发布时间】:2014-01-27 16:24:44
【问题描述】:
interface A {
}

public class B {
    public static void main(String a[]) {
        Class c = Class.forName("A");
        System.out.println(c.isInterface());//false
        Class c1 = A.class;
        System.out.println(c1.isInterface());//true
    }
}

o/p: 错误的 真的

预期 o/p: 真的 真的

我不知道这两者的区别: Class.forName("A") 和 A.class 非常感谢。

【问题讨论】:

  • 您确定这是您正在运行的代码吗?这些类型中的任何一种都包含在一个包中吗?
  • 这可以很好地解释差异:stackoverflow.com/questions/10947768/…
  • 您的代码无法编译。

标签: java


【解决方案1】:

Class.forName() 尝试在运行时解析一个类,使用默认的类加载器。它可能成功,也可能失败,具体取决于所需的类是否有效以及在您的类路径中。

.class 运算符将类描述符评估为编译时常量。如果引用的类无效并且存在于类路径中,它仍然可能在运行时失败,但它可以用于需要常量表达式的地方(例如,在注释值中),并且它通常在重构方面更具弹性。请注意,捕获的类描述符取决于编译器的输入和类路径;使用不同的编译器参数,相同的代码最终可能会引用两个不同的类。

在您的用例中,两者都应该解析为同一个类。您的结果出乎意料,可能表明您的类路径中存在另一个名为 A 的类。我怀疑您在问题中引用的接口A 实际上位于一个包中,在这种情况下,您将错误的描述符传递给forName()。名称应该是包限定的。

【讨论】:

    【解决方案2】:

    如果你写A.class,编译器需要在编译时知道A。

    如果你写Class.forName("A"),那么它只在运行时需要。

    【讨论】:

    • 您还没有回答 OP 的问题。他想知道为什么 A.class.isInterface() 和 Class.forName("A").isInterface() 返回不同的值。
    • 我认为问题更多的是关于输出。
    • 引用 OP:“我不知道这两个的区别:Class.forName("A") 和 A.class 非常感谢。”
    • @richardtz 是的,但上下文是在他显示“预期输出”和“输出”之后。
    • 也许你是对的,我的回答已经多次被否决,我认为这不公平。也许有更好的答案,事实上我已经投了另一个答案,但我发现这种情况如此频繁地发生有点令人作呕。
    【解决方案3】:

    它为Runtime error 提供了 java 中 try 和 catch 或 throws 的环绕

    这样做,得到true true

    interface A{
    }
    
    public class B{
    public static void main(String a[]) throws ClassNotFoundException{
    Class c= Class.forName("A");
    System.out.println(c.isInterface());
    Class c1=A.class;
    System.out.println(c1.isInterface());
    }
    }
    

    输出

    true
    true
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 2012-06-23
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多