2

我有一个Student类和一个StudentPool定义如下的类:

public class Student {
    public Student copy () {
        return new Student();
    } 
}

public class StudentPool<T extends Student> {
    public T copyStudent(T t) {
        return t.copy();
    }
}

因此,该copyStudent方法无法编译,我必须使用不安全的类型转换。我不明白为什么 Java 确实认为这是非法的?

编辑: user845279、lcfseth 和 Bohemian:我认为对 Student 的以下修订可能会导致类似的情况,将父类转换为其子类,但此版本可以通过编译:

public class Student {
    public <T extends Student> T copy() {
       T rv = null; 
       return rv;
    } 
}

编辑: 忘记上面的代码:rv可以null或不安全地铸造。

4

3 回答 3

4

假设您有一个SmartStudent扩展的类Student和一个StudentPool<SmartStudent>. 在这种情况下copyStudent,应该采用 aSmartStudent并返回 a SmartStudent,但是 in 中的实现Student并没有这样做——它只返回一个普通的Student实例。

编辑:

为了实现你想要的模式,你可以给Student它的所有子类一个复制构造函数

public class Student {
    public Student(Student other) {
        //copy other's Student fields to this instance
    } 
}

public class SmartStudent extends Student {
    public SmartStudent(SmartStudent other) {
        super(other);
        //copy other's SmartStudent fields to this instance
    }
}

StudentPool抽象:

public abstract class AbstractStudentPool<T extends Student> {
    public T copyStudent(T original);
}

每个AbstractStudentPool实现都会调用适当的复制构造函数:

public class SmartStudentPool extends AbstractStudentPool<SmartStudent> {
    @Override
    public SmartStudent copyStudent(SmartStudent original) {
        return new SmartStudent(original);
    }
}
于 2012-05-11T01:27:49.847 回答
2

问题是,虽然从中Student返回,子类也会返回......而不是它们自己的类型。Studentcopy()Student

这是解决您的问题的方法:

public static interface Copyable<T> {
    public T copy();
}

public static class Student implements Copyable<Student> {
    @Override
    public Student copy() {
        return new Student();
    }
}

public static class StudentPool<T extends Student> {
    public T copyStudent(Copyable<T> t) {
        return t.copy();
    }
}

作为旁注,您似乎在这里不需要泛型。

于 2012-05-11T01:35:19.447 回答
0

您不能将父类转换为其子类。隐式强制转换只能反其道而行之。即使使用显式类型转换,这也极有可能产生运行时错误。

于 2012-05-11T01:28:45.413 回答