使用class.cast()方法的java嵌套转换

cuxqih21  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(328)

我有一个 Person 类,它实现 Cloneable . 然后我就有了对象 p 以及 o 哪个参考a Person 对象。我试图将一个克隆到另一个,并发现以下方法有效:

Object p = new Person("Heather");
Object o = ((Person)p).clone();

(我不得不用那个石膏,因为 clone() 在对象中受保护。我用这个打电话 clone()Person 相反。)
我需要知道的是如何使用 Class.cast() . 我知道怎么投一次,大概是这样的:

Object o = p.getClass().cast(p);

但是如何以这种方式执行嵌套的casting示例(我需要知道,因为在这个项目中,我并不总是知道投给什么类,但我会知道类是什么 Cloneable .)
我试过…((cloneable)p).clone()…但那不起作用。clone()方法是对象类中受保护的方法,接口cloneable没有clone()方法,因此编译器无法识别它。
我到处找答案,到处都找不到。谢谢你的帮助。

u59ebvdq

u59ebvdq1#

这是一件困难的事情,因为克隆人的工作方式。正如您所注意到的,clone几乎是一个受保护的方法,因此您需要在编译时使用一个类来调用它。有一种方法可以解决这个问题,那就是声明一个接口,为其分配公共访问权:

public interface PublicCloneable
extends Cloneable {
    public Object clone();
}

然后实现它而不是克隆。然后您可以强制转换到publiccloneable来调用克隆。这将正常工作,但它仍然带有所有的克隆正常的问题。
创建复制构造函数是克隆的一个很好的替代方法,如果在编译时不知道类,可以创建一个方法来使用反射调用它:

static Object reflectionCopy(Object obj) {
    try {
        Class<?> cls = obj.getClass();
        Constructor<?> ctor = cls.getConstructor(cls);
        return ctor.newInstance(obj);
    } catch(Exception e) {
        return obj;
    }
}

( getClass 总是返回 Class<?> 因此,如果您不介意未选中的强制转换,也可以将其设置为通用的。)
可能你在这里遇到的是一个迹象,你需要考虑你的设计。就我个人而言,这听起来像是一个通用工厂可能是有利的情况。
基本上是这样的:

public interface Copier<T> {
    public T createCopy(T obj);
}

public class PersonCopier
implements Copier<Person> {
    @Override
    public Person createCopy(Person person) {
        return new Person(person.getName());
    }
}

public static <T> T doStuffInvolvingCopy(T inObject, Copier<T> copier) {
    ...

    T copy = copier.createCopy(inObject);

    ...

    return copy;
}

你可以这样说

doStuffInvolvingCopy(new Person("Heather"), new PersonCopier());

或者把工厂注册在某个地方,这样就不需要到处转手了。
工厂之所以好,是因为它们不使用克隆,也不使用反射。

z4iuyo4d

z4iuyo4d2#

使用 clone() 在代码中是不寻常的(我从来没有使用过它,也没有见过它像那样显式地使用)。
通常用于复制的模式是复制构造函数,例如:

public class Person {
    private String name;
    public Person(String name) {
       this.name = name;
    }

    // Copy constructor
    public Person(Person person) {
        this(person.name);
    }
}

源对象的重要字段的值用于初始化新对象的字段值。

相关问题