Java 方法返回classCastException
假设我有一个扩展Employee的Employee基类和Manager子类。现在假设我创建了Employee类型的对象x和Manager类型的对象y,并调用Java 方法返回classCastException,java,compareto,Java,Compareto,假设我有一个扩展Employee的Employee基类和Manager子类。现在假设我创建了Employee类型的对象x和Manager类型的对象y,并调用x.compareTo(y)没有触发异常,x和y作为雇员进行比较,即y被强制转换为雇员,但当我调用y.compareTo(x)时我得到一个classCastException。我需要知道为什么会发生这种情况,以及如何防止x.compareTo(y)执行,因为x和y来自不同的类。我的想法是在反射类中使用getclass()方法,如下所示: if
x.compareTo(y)
没有触发异常,x和y作为雇员进行比较,即y被强制转换为雇员,但当我调用y.compareTo(x)时
我得到一个classCastException。我需要知道为什么会发生这种情况,以及如何防止x.compareTo(y)执行,因为x和y来自不同的类。我的想法是在反射类中使用getclass()方法,如下所示:
if (getClass() != other.getClass())
throw new ClassCastException();
我还想知道有没有其他方法来实现这一点。这里的
经理是一名员工
但是员工
不是经理
引用有效Java第12项:
让我们看一下合同的条款。第一条规定说,如果你颠倒两个对象参照之间的比较方向,预期的事情就会发生:如果第一个对象小于第二个对象,那么第二个对象必须大于第一个对象;如果第一个对象等于第二个对象,则第二个对象必须等于第一个对象;如果第一个物体大于第二个物体,那么第二个物体必须小于第一个物体。第二条规定,如果一个物体大于第二个物体,第二个物体大于第三个物体,那么第一个物体必须大于第三个物体。最后一条规定是,当与任何其他对象进行比较时,所有作为相等对象进行比较的对象必须产生相同的结果
这三条规定的一个结果是,比较法施加的平等测试必须遵守平等合同施加的相同限制:自反性、对称性和及物性。因此,同样的警告也适用:除非您愿意放弃面向对象抽象的好处(第8项),否则在保留compareTo契约的同时,无法使用新的值组件扩展可实例化类。同样的解决方法也适用。如果要向实现Comparable的类添加值组件,请不要扩展它;编写一个不相关的类,其中包含第一个类的实例。然后提供一个返回此实例的“view”方法。这使您可以在第二个类上实现您喜欢的任何compareTo方法,同时允许其客户端在需要时将第二个类的实例视为第一个类的实例。因为您的经理是员工
,但员工不是经理
请参见下文
的实例在这种情况下可用所有经理
都是员工
,但并非所有员工
都是经理
。由于Employee
的所有属性在Manager
中可用,Manager
可以强制转换为Employee
。但是Manager
的属性对Employee
不可用,因此无法进行强制转换
我的建议是在类中重写compareTo()
方法,并强制转换对象Employee
,您应该在类Employee
中实现compareTo()
,并从以下内容开始:
Employee o = (Employee)other;
然后继续将此
与o
进行比较-这将确保您比较的是两名员工
s(最低公分母).您可以使用isAssignableFrom,它将返回true或false,然后使用它进行进一步的比较或相等等。不确定您为什么需要这个来进行比较;不过
无论如何,假设员工的姓名、工资和经理的一组报告对象,然后进一步比较工资作为比较的一部分
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
}
}
公共类测试{
公共静态void main(字符串[]args){
类Employee实现了可比较的{
公共雇员(字符串,整数工资){
this.name=字符串;
这个。薪水=薪水;
}
公职人员(){
name=“”;
工资=0;
}
字符串名;
整数工资;
公共内部比较(员工o){
return o!=null&&getClass().isAssignableFrom(Employee.class)
?薪资。比较(o.salary):整数最小值;
}
}
类管理器扩展雇员{
公共经理(字符串名称,字符串[]下属){
超级(名称,1000000);
被报道者=下属;
}
字符串[]报告对象;
}
员工e=新员工(“我”,1000);
雇员e1=新雇员(“mycolleague”,2000年);
经理m=新经理(“我的老板”、“我的同事”)。拆分(“”);
系统输出打印ln(e1.与(e)比较);
系统输出println(e.compareTo(m));
System.out.println(m.compareTo(e));//这会给出INT.MIN,因为您无法比较经理和员工
}
}
您想在两名员工之间比较什么?薪水?:)@卢声远生源路不,这只是一个例子,我的代码太大了,不能在这里发布。是的,我知道,但我也想阻止执行的x.compareTo(y),我的想法是使用getclass(),我想知道还有其他方法吗?@user1613360请参见alfasin的答案。这并不能回答这个问题。若要评论或要求作者澄清,请在他们的帖子下方留下评论。@Payeli我要求他思考“是一种”关系。请查看
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
}
}