我有2个小班(学生,老师)和一个超级班(职业)
我从学生创建了对象A,从教师创建了对象B.
Student A = new Student();
Teacher B = new Teacher();
我已经创建了一个静态方法,它将对象作为参数并返回boolean;
compare(A, B);
public static boolean compare(Student s, Teacher t)
在方法中,我只是将此代码用于比较两个对象是否属于同一个类;
if (s.getClass() == t.getClass())
现在我收到错误说:
incomparable types: Class<CAP#1> and Class<CAP#2>
其中CAP#1,CAP#2是新的类型变量:
CAP#1 extends Student from capture of ? extends Student
CAP#2 extends Teacher from capture of ? extends Teacher
这里有什么问题?
注意:如果我使用比较s.equals(t),它根本没有任何错误。为什么我不能正确使用object.getClass()方法?
答案 0 :(得分:1)
我想你想要这样的东西:
public static boolean compare(Object o1, Object o2)
然后可以使用instanceof
进行比较,例如if(o1 instanceof Teacher && o2 instanceof Student)
引发异常是因为getClass()
返回Class<? extends Object>
并且错误消息告诉您,这些类是无法比拟的,因为学生和教师将返回不同的类(我认为你的错误是假设有返回类似字符串的东西)。
答案 1 :(得分:1)
如果class Student extends Occupation
和class Teacher extends Occupation
,那么就没有同时属于Student
和Teacher
的课程。因此,尝试比较它们毫无意义。 s.getClass() == t.getClass()
总是会返回false。
编译器可以检测到,因为对于任何类型T,T.getClass()
都会返回Class<? extends T>
。 Class<? extends Student>
和Class<? extends Teacher>
永远不会相互平等,因此无法比拟。
如果你想比较它们,你需要说服编译器类型确实具有可比性。您可以将方法签名(由@Seismoid建议)更改为compare( Object o1, Object o2)
或通过显式向上转换为Class<?>
甚至Class
(我感觉原始类型警告在这里)或Object
:
return ((Class<?>) s.getClass()) == ((Class<?>) t.getClass());
根据s.equals(t)
的原因,这是因为T.equals
的签名是public boolean equals(Object)
,而不是public boolean equals(T)
,因此编译器无法始终检查比较返回false。实际上,它甚至可能不会返回false,因为您可以创建一个等于来自不同类的对象的对象。
你不能覆盖==
,所以编译器知道比较是无关紧要的,因为不能是同一个类的对象彼此不能相同(除非两者都是 null - 你应该以不同的方式检查它。
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.21.3说:
如果无法通过强制转换(§5.5)将任一操作数的类型转换为另一种操作数的类型,那么这是一个编译时错误。两个操作数的运行时值必然不相等。