Object.getClass()方法的签名

时间:2010-07-05 21:19:23

标签: java generics

Object类包含以下方法:

public final Class<? extends Object> getClass().

为什么此方法的返回类型为Class<? extends Object>

5 个答案:

答案 0 :(得分:3)

因为Java缺少self types。 (如果有,则返回类型为Class<? extends self_type>)。所以签名只是声明Class<?>,它可以做的最好(下一个),这不是理想的 - 编译器当然知道getClass()不会返回任何类,而是一个类< strong>子类型表示调用getClass()的表达式的静态类型。

因此我们有这个奇点,由于语言的限制,方法的签名声明Class<?>,但编译器将返回值视为Class<? extends TheClass>,因为它知道它是安全的并且想要乐于助人:)

PS:您看到了Class<? extends Object>,因为您在静态类型为getClass()的表达式上调用了Object

答案 1 :(得分:2)

这实际上是JDK 1.5中的一个错误。另请参阅this topicthis bugreport。在一个坚果中,这个签名导致以下代码片段在应该时无法编译:

List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass()); // Incompatible types?

他们通过将返回类型更改为Class<?>而非Class<? extends Object>将其修复为1.6。

答案 2 :(得分:1)

因为,泛型构造? extends Object匹配任何扩展Object的Java对象。由于Java中的所有内容都继承自Object,因此它会匹配类路径中加载的所有内容。在这种情况下,不使用Class<? extends Object> Object.getClass()方法只能返回对象类,而不是像大多数开发人员所期望的那样返回表示实际具体类型的Class对象。

答案 3 :(得分:1)

实际签名(至少在1.6中)是

public final Class<?> getClass()

根据javadocs:

  

实际结果类型是Class,其中| X |是擦除   表达式的静态类型   在哪个getClass被调用。对于   例如,此处不需要强制转换   代码片段:

     

数字n = 0;
  等级&lt; ? extends Number&gt; c = n.getClass();

如果您没有参数化返回值,即使您在运行时可以获得类型信息,也必须进行强制转换。所以上面的例子最终将成为

Class c = n.getClass(); //c now has no type information

答案 4 :(得分:0)

getClass()方法(通常)用于检查类是否属于特定类型

MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();

if (myClass.getClass().equals(myClass2.getClass())
{
  // do stuff
}

返回类型是一个Class对象,因为您可以将它与其他Class对象进行比较。它扩展了Object,因为所有东西都在Java中扩展了对象。

getClass()的另一个用途是使用getName()以便

myClass1.getClass().getName() 

返回MyClass

它可以帮助您通过反射

按字符串名称实现类
string className = myClass1.getClass().getName();
MyClass newInstance = (MyClass) Class.forName(className).newInstance();