Reputation: 25
I have 2 sub-class (Student, Teacher) and a superclass (Occupation).
I have created Object A from Student and Object B from Teacher.
Student A = new Student();
Teacher B = new Teacher();
And I already created a static method that takes objects as arguments and returns boolean;
compare(A, B);
public static boolean compare(Student s, Teacher t)
In the method, I just put this code to compare if both object belong to the same class or not;
if (s.getClass() == t.getClass())
And now I get the error saying:
incomparable types: Class<CAP#1> and Class<CAP#2>
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Student from capture of ? extends Student
CAP#2 extends Teacher from capture of ? extends Teacher
What is wrong here ?
NOTE: If I use the comparison s.equals(t), it doesn't have any error at all. Why can't I use the object.getClass() method correctly ?
Upvotes: 0
Views: 4160
Reputation: 27287
If class Student extends Occupation
and class Teacher extends Occupation
, then there is no class that is both a Student
and a Teacher
. Thus there's no point in trying to compare them. s.getClass() == t.getClass()
would always return false.
The compiler can detect that, since, for any type T, T.getClass()
returns Class<? extends T>
. Class<? extends Student>
and Class<? extends Teacher>
are never equal to each other and thus incomparable.
If you do want to compare them, you need to convince the compiler the types are indeed comparable. You could change the method signature (as suggested by @Seismoid) to compare( Object o1, Object o2)
or by explicit upcasting to Class<?>
or even Class
(I sense a raw types warning here) or Object
:
return ((Class<?>) s.getClass()) == ((Class<?>) t.getClass());
as per why s.equals(t)
works, this is because the signature of T.equals
is public boolean equals(Object)
, not public boolean equals(T)
, so the compiler has no way to check the comparison will always return false. Indeed, it may not even return false as you can create an object that equals objects from a different class.
You cannot override ==
, so the compiler knows the comparison is immaterial as objects that cannot be the same class cannot be identical to each other (unless both are null - and you should check that in a different way).
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.21.3 says:
It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.
Upvotes: 1
Reputation: 146
I think you want something like this:
public static boolean compare(Object o1, Object o2)
and then maybe use instanceof
to compare like if(o1 instanceof Teacher && o2 instanceof Student)
The exception is thrown because getClass()
returns a Class<? extends Object>
and like the error message tells you, those classes are incomparable because Student and Teacher will return different classes (I think your mistake is to assume there is returned something like a string).
Upvotes: 1