The class Object contains the following method:
public final Class<? extends Object> getClass().
why the return type of this method is Class<? extends Object>
The class Object contains the following method:
public final Class<? extends Object> getClass().
why the return type of this method is Class<? extends Object>
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();
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.
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
.
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
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>
.