Java 使用泛型在抽象类中实现公共方法

Java 使用泛型在抽象类中实现公共方法,java,generics,Java,Generics,假设我有这样的层次结构: public abstract class AbstractEntity implements Cloneable { ... public AbstractEntity clone() { Cloner cloner = new Cloner(); AbstractEntity cloned = cloner.deepClone(this); return cloned; } } public

假设我有这样的层次结构:

public abstract class AbstractEntity implements Cloneable {
    ...
    public AbstractEntity clone() {
        Cloner cloner = new Cloner();
        AbstractEntity cloned = cloner.deepClone(this);
        return cloned;
    }
}

public class EntityA extends AbstractEntity {
    ...
}
这很好,我可以做到:

EntityA e1 = new EntityA();
EntityA e2 = (EntityA) e1.clone();
但我得手工打字。 有没有一种方法可以使用java泛型让clone()方法返回子类的实际类型


谢谢大家!

我能想到的最接近的是:

public abstract class AbstractEntity<T extends AbstractEntity<T>> 
    implements Cloneable {

    @SuppressWarnings("unchecked")
    public T clone() {
        Cloner cloner = new Cloner();
        T cloned = (T) cloner.deepClone(this);
        return cloned;
    }    
}

public class EntityA extends AbstractEntity<EntityA> { 
    ...
}

public class EntityB extends AbstractEntity<EntityB> { 
    ...
}
公共抽象类AbstractEntity
可克隆的{
@抑制警告(“未选中”)
公共T克隆(){
克隆人克隆人=新克隆人();
T clone=(T)cloner.deepClone(this);
返回克隆;
}    
}
公共类EntityA扩展了抽象实体{
...
}
公共类EntityB扩展了AbstractEntity{
...
}
这并不完全安全:你可以写:

public class EvilClass extends AbstractEntity<EntityA> { 
    ...
}
公共类扩展抽象实体{
...
}

。。。但这对您是否重要取决于您的用例。

我认为不需要泛型。您可以在抽象类中声明clone()方法,并重写它以返回子类中的子类

package inheritance;

public abstract class AbstractEntity {

    public abstract AbstractEntity clone();
}


package inheritance;

public class ClassA extends AbstractEntity {

    @Override
    public ClassA clone() { return null; }

}


package inheritance;

public class Driver {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ClassA a = new ClassA();
        ClassA b = a.clone();
        System.out.println("all done");
    }

}

这不是你想要做的吗?

克隆行为不是类型特定的,所以他希望避免一系列不必要的重写。我认为这比使用泛型麻烦更少,更干净;希望OP能让我们知道这是否适合他的情况。如果克隆行为不是类型特定的,那么他没有理由不能让子类调用超类方法;然后,他有了通用的克隆代码,不必强制转换他的结果,他也没有使用泛型的奇怪类,也没有现有基于泛型的答案中提到的“邪恶实体”的可能性。代价是在每个子类中都有一个方法来调用super并返回正确的类型。我同意。泛型应该是关于类型安全的,而不是更少的类型,所以这种方法实际上很有意义。erickson和rcook,你们都是对的:是的,我想要避免重写,是的,我想要一个完整的类型安全,没有尴尬的工件。我明白我不能同时做到这两个,所以最好的解决办法是这样。嗯。。。这就是我所害怕的:为了有一个对类本身类型的引用,我必须将它声明为“同一类的一个类的一个类”;-)不错的技巧,顺便说一句,它对我更好地学习Java很有用。非常感谢。