Java:如何将克隆的对象强制转换为其原始子类?

想象一下超级A类:

public class A {
    private int x;

    A(int x){
        this.x = x;
    }

    public int getX() {
        return x;
    }
}

它是B和C的2个子类:

public class B extends A{
    private int y = 2;

    B(int x){
        super(x);
    }
}
public class C extends A{
    private int y = 3;

    B(int x){
        super(x);
    }
}

现在想象一下所有都继承类A的对象的列表。我想遍历该列表并克隆每个对象,并将其强制转换为它的原始子类(B或C)。这就是我试图做到的方式:

public static void main(String args[]) {
    ArrayList<A> aList = new ArrayList<A>();
    aList.add(new B(5));
    aList.add(new C(6));

    ArrayList<A> aClones = new ArrayList<A>();

    for(A a : aList) {
        A aNew = new A(a.getX());
        a.getclass().cast(aNew);
        aClones.add(aNew);
    }
}

但是这给了我一个错误,说我不能将A强制转换为B。如何在不预先知道要处理的对象子类型的情况下实现此目标?我可以在for循环中为每种类型的子类执行if语句,以检查a是否是该子类的实例,然后简单地创建该特定子类的新实例并以这种方式对其进行克隆。但是,在我的情况下,将有更多的子类,而不仅仅是B和C,并且可能还会有更多的子类。我不希望for循环包含有关A的现有子类的任何知识。这可能吗?

ilovec_ola 回答:Java:如何将克隆的对象强制转换为其原始子类?

您可以这样做

for(A a : aList) {
    A anew;
    if (a.getClass() == A.class) anow = new A(a.getX());
    else if (a.getClass() == B.class) anow = new B(a.getX());
    else if (...

}

,

这不能以您编写的方式完成。

原因很简单:BCA is-a 关系,但是A不共享与BC相同的关系。

这主要是因为您要尝试使用超类来描述所有内容。

for(A a : aList) { }

要迭代时,您无法从类型推断中单独了解 实际上是什么具体类A

所以这失败了,如预期的那样。

 a.getClass().cast(aNew);

没有明确询问班级是什么类型,您就无法做到这一点。

这意味着,如果您打算在此基础上进行扩展,将会写很多instanceof语句。

for(A a : aList) {
    if(a instanceof B) {
        B b = new B(a.getX());
        aClones.add(b);
    }
    if(a instanceof C) {
        C c = new C(a.getX());
        aClones.add(c);
    }
}
,

您应该使用子类的构造函数将其克隆。 否则,它将是无法转换为C或B的超类A的类型。 参见例如反思:http://tutorials.jenkov.com/java-reflection/constructors.html

或者更好地使用克隆功能。 https://en.m.wikipedia.org/wiki/Clone_(Java_method)

那应该容易得多。

本文链接:https://www.f2er.com/2910756.html

大家都在问