比较具有相同超类的2个子类实例

时间:2012-12-02 12:54:03

标签: java inheritance subclass superclass

我有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()方法?

2 个答案:

答案 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 Occupationclass Teacher extends Occupation,那么就没有同时属于StudentTeacher的课程。因此,尝试比较它们毫无意义。 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)将任一操作数的类型转换为另一种操作数的类型,那么这是一个编译时错误。两个操作数的运行时值必然不相等。