Object类包含以下方法:
public final Class<? extends Object> getClass().
为什么此方法的返回类型为Class<? extends Object>
答案 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 topic和this 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();