开发者

signature of Object.getClass() method

开发者 https://www.devze.com 2023-01-06 14:03 出处:网络
The class Object contains the following me开发者_Go百科thod: public final Class<? extends Object> getClass().

The class Object contains the following me开发者_Go百科thod:

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

why the return type of this method is Class<? extends Object>


Because Java lacks self types. (If it had them, then the return type would be Class<? extends self_type>). So the signature merely declares Class<?>, the (next) best it can do, which is less than ideal - the compiler certainly knows that getClass() doesn't return any class, but a class that is a subtype of the static type of the expression on which getClass() is invoked.

Thus we have this singularity, where the signature of the method declares Class<?> because of limitations of the language, but the compiler treats the return value as Class<? extends TheClass> because it knows it is safe and wants to be helpful :)

PS: you saw Class<? extends Object> because you called getClass() on an expression with the static type of Object.


This was actually a bug in JDK 1.5. Also see this topic and this bugreport. In a nut, this signature caused that the following snippet didn't compile while it should:

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

They fixed it in 1.6 by changing the return type to Class<?> instead of Class<? extends Object>.


Because, the generic construct ? extends Object matches any Java object which extends Object. Since everything in Java inherits from Object, this matches everything loaded on the classpath. In this case, without using Class<? extends Object> the Object.getClass() method would only ever be able to return the Class of Object, and not the Class object representing the actual concrete type as most developers would expect.


The actual signature (at least in 1.6) is

public final Class<?> getClass()

According to the javadocs :

The actual result type is Class where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:

Number n = 0;
Class < ? extends Number> c = n.getClass();

If you didn't have a parameterized return value, you'd have to cast even if you had type information available at runtime. So the above example would end up as

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


The getClass() method is (usually) used to check if a class is of a particular type

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

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

The return type is a Class object because you can compare it to other Class object. It extends Object because everything extends object in Java.

Another use of getClass() is to use getName() so that

myClass1.getClass().getName() 

returns MyClass

It can help you instanciate classes by string name via reflection

string className = myClass1.getClass().getName();
MyClass newInstance = (MyClass) Class.forName(className).newInstance();
0

精彩评论

暂无评论...
验证码 换一张
取 消