Java compareTo()方法返回classCastException

时间:2014-06-05 04:35:55

标签: java compareto

假设我有一个Employee基类和Manager子类,它扩展了Employee.Now让我说我创建一个Employee类型的对象x和类型为Manager的对象y并调用x.compareTo(y)没有异常被触发,x和y被比较为Employees,即y被强制转换为Employee,但当我调用y.compareTo(x)时,我得到一个classCastException。我需要知道为什么会发生这种情况以及如何防止x.compareTo(y)执行x和y来自不同的类。我的想法是在Reflection类中使用getclass()方法,如下所示:

if (getClass() != other.getClass()) 
throw new ClassCastException();

我也想知道有没有其他方法可以实现这一点。

6 个答案:

答案 0 :(得分:3)

您应该在课程compareTo()中实施Employee并以:

开头
Employee o = (Employee)other;

然后继续将thiso进行比较 - 这将确保您比较两个Employee(这是最低的公分母)。

答案 1 :(得分:2)

此处Manager Employee

Employee不是Manager

引自Effective Java,第12项:

让我们回顾一下compareTo合同的规定。第一条规定说,如果你反转两个对象参考之间的比较方向,预期的事情就会发生:如果第一个对象小于第二个对象,那么第二个对象必须大于第一个对象;如果第一个对象等于第二个对象,则第二个对象必须等于第一个对象;如果第一个对象大于第二个对象,那么第二个对象必须小于第一个对象。第二条规定,如果一个物体大于一秒,第二个物体大于三分之一,那么第一个物体必须大于第三个物体。最后的规定说,与其他任何对象相比,所有比较相等的对象必须产生相同的结果。

这三个规定的一个结果是,acompareTo方法所施加的相等性测试必须遵循等同合同所施加的相同限制:反身性,对称性和传递性。因此,同样的警告适用:除非您愿意放弃面向对象抽象的好处(第8项),否则无法在保留compareTo契约的情况下使用新值组件扩展可实例化类。同样的解决方法也适用。如果要将值组件添加到实现Comparable的类中,请不要扩展它;编写一个包含第一个类实例的无关类。然后提供一个返回此实例的“视图”方法。这使您可以在第二个类上实现您喜欢的任何compareTo方法,同时允许其客户端在需要时将第二个类的实例视为第一个类的实例。

答案 2 :(得分:2)

因为您的Manager is an EmployeeEmployee is not a Manager见下文

http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

在这种情况下,

instance of可能很有用

答案 3 :(得分:0)

所有Manager都是Employee,但并非所有Employee都是Managers。由于Employee中可以使用Manager的所有属性,因此Manager可以投放到Employee。但是Manager的属性不可用于Employee,因此无法投射。

我的建议是在您的类中覆盖compareTo()方法并转换对象Employee

答案 4 :(得分:0)

If your are using compareTo method then i am excepting you have implemented Comparable interface in your class and provide a implementation of the method compareTo. let me know how you are comparing object on what logic ,based on that only you get the solution.

I have little bit confuse on this 
if (getClass() != other.getClass()) 
throw new ClassCastException();

if it is the code in your compareTo method then rather then doing this create one more interface say "XYZ" and implement that Interface to both the class
check the logic 


    public int compareTo(T obj){
    if(this instanceof XYZ &&  obj instanceof XYZ)){
return 0;
    }else{
    throw new ClassCastException();
    }
    }

答案 5 :(得分:0)

您可以使用isAssignableFrom,它将返回true或false,然后使用它进行进一步的比较或等于等等。不确定为什么在compareTo中需要这个;但是。

无论如何,假设一名员工的姓名,薪水和经理的一组报告,然后进一步比较工资作为compareTo的一部分。

public class Test{   
    public static void main(String[] args) {
        class Employee implements Comparable<Employee> {
            public Employee(String string, int salary) {
                this.name = string;
                this.salary = salary;
            }

            public Employee() {
                name = "";
                salary = 0;
            }

            String name;
            Integer salary;

            public int compareTo(Employee o) {
                return o!=null && getClass().isAssignableFrom(Employee.class)
                        ? salary.compareTo(o.salary) : Integer.MIN_VALUE;
            }

        }

        class Manager extends Employee {
            public Manager(String name, String[] subordinates) {
                super(name, 1000000);
                reportees = subordinates;
            }

            String[] reportees;
        }

        Employee e = new Employee("me", 1000);
        Employee e1 = new Employee("mycolleague", 2000);
        Manager m = new Manager("myboss", "me mycolleague".split(" "));
        System.out.println(e1.compareTo(e));
        System.out.println(e.compareTo(m));
        System.out.println(m.compareTo(e)); // this gives INT.MIN as you cannot compare manager to employee
    }

}