【问题标题】:What does Class<?> mean in Java?Java 中的 Class<?> 是什么意思?
【发布时间】:2021-01-02 15:36:42
【问题描述】:

我的问题如上。抱歉,这可能是重复的,但我找不到末尾带有 &lt;?&gt; 的示例。

为什么不直接使用Class 作为参数?

【问题讨论】:

标签: java syntax


【解决方案1】:

Class 是一个可参数化的类,因此您可以使用语法Class&lt;T&gt;,其中T 是一个类型。通过编写Class&lt;?&gt;,您声明了一个可以是任何类型的Class 对象(? 是一个通配符)。 Class 类型是包含有关类的元信息的类型。

通过使用Class&lt;?&gt; 指定泛型类型来引用泛型类型始终是一种好习惯,您尊重这种做法(您知道Class 是可参数化的),但您并没有限制您的参数具有特定类型。

关于泛型和通配符的参考:http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

关于Class对象和反射(Java语言自省特性)参考:https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html

【讨论】:

  • 与仅使用Class 而不使用类型相比,这样做有什么好处?它们似乎代表着同样的东西。
  • 我认为泛型的全部意义在于您事先不知道类类型。否则,您只需定义一个函数来为参数使用特定的类类型。这个问号还是没有意义。
  • 除了你告诉编译器“我知道这是一个泛型类,但我不知道也不关心实际类型,所以没有其他好处,所以不要给出具体类型我给了? 通配符。”。如果您不提供通配符,编译器会假定您忘记了类型或不知道该类是泛型的,并会警告您。
  • Class&lt;?&gt; 的 Kotlin 等价物是什么
  • 只是Class不能传递给Class&lt;?&gt;类型的参数,所以Class&lt;?&gt;更适合所有情况。
【解决方案2】:

这个&lt;?&gt; 是一头野兽。它通常会导致混淆和错误,因为当您第一次看到它时,您就会开始相信,&lt;?&gt;任何 java 类型的通配符。这是..不是真的。 &lt;?&gt;未知类型,有细微的差别。

Class 一起使用没有问题。这两行都可以工作并编译:

Class anyType = String.class;
Class <?> theUnknownType = String.class;

但是 - 如果我们开始将它与集合一起使用,那么我们会看到奇怪的编译时错误:

List<?> list = new ArrayList<Object>();  // ArrayList<?> is not allowed
list.add("a String");                    // doesn't compile ...

我们的List&lt;?&gt; 不是一个集合,它适用于任何类型的对象。它只能存储一种类型:神秘的“未知类型”。这肯定不是真正的类型。

【讨论】:

    【解决方案3】:

    这意味着您的 Class 引用可以包含对任何 Class 对象的引用。

    它与“Class”基本相同,但您向阅读您的代码的其他人展示了您没有忘记泛型,您只需要一个可以包含任何 Class 对象的引用。

    Bruce Eckel,用 Java 思考:

    在 Java SE5 中,Class> 优于普通 Class,即使它们 是等价的,正如你所见,普通的 Class 不会产生 编译器警告。 Class> 的好处是它 表示您不只是使用非特定类引用 意外,或出于无知。您选择了非特定版本。

    【讨论】:

    • 引用说“Class> 优于普通 Class”和“Class> 的好处”。似乎 blockquote 不同意尖括号。
    • 需要转义。现在修复它:P
    【解决方案4】:

    这是一个 generics 文字。这意味着您不知道这个Class 实例所代表的类的类型,但您仍在使用泛型版本。

    • 如果你知道这个类,你会使用Class&lt;Foo&gt;。这样您就可以创建一个新实例,例如,无需强制转换:Foo foo = clazz.newInstance();
    • 如果您根本不使用泛型,至少会收到警告(通常不鼓励使用泛型,因为它可能会导致难以检测的副作用)

    【讨论】:

      【解决方案5】:

      在泛型中,未知类型由通配符“?”表示。阅读here获取官方示例。

      【讨论】:

        【解决方案6】:

        这意味着具有任何类型(未知)的类。

        您应该阅读 java 泛型教程以更好地理解它

        【讨论】:

          【解决方案7】:

          这意味着,Class 引用类型可以包含代表任何类型的任何 Class 对象。如果 JVM 加载一个类型,代表该类型的类对象将出现在 JVM 中。我们可以从反射包中经常使用的类对象中获取有关类型的元数据。

          假设您有一个名为“myPackage.MyClass”的类。假设在类路径中,以下语句是等价的。

          Class<?> myClassObject = MyClass.class; //compile time check
          
          Class<?> myClassObject = Class.forname("myPackage.MyClass"); //only runtime check
          

          如果 Class> 引用也在方法参数中,则以类似的方式工作。

          请注意,“Class”类没有公共构造函数。所以你不能用“new”操作符来实例化“Class”实例。

          【讨论】:

            猜你喜欢
            • 2013-02-11
            • 2012-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-02-10
            • 2019-06-16
            • 1970-01-01
            相关资源
            最近更新 更多