我定义了一个Java接口来表示对象复制自身的能力(不,我不想使用Cloneable,但是感谢您的建议;-)。它是通用的:

public interface Copiable<T> {
    T copy();
}

对象只会复制其自身类型的副本:
public class Foo implements Copiable<Foo> {
    Foo copy() { return new Foo(); }
}

现在,我正在从一个非通用API(Hibernate元数据,如果任何人都感兴趣)中读取Class<?>对象,并且,如果它们是Copiable,我想在我的一个组件中注册它们。 register方法具有以下签名:
<T extends Copiable<T>> register(Class<T> clazz);

我的问题是,如何在将类传递给方法之前进行强制转换?我目前正在做的是:
Class<?> candidateClass = ...
if (Copiable.class.isAssignableFrom(candidateClass)) {
    register(candidateClass.asSubclass(Copiable.class));
}

这是我想要的,但是带有编译器警告。而且我认为我将无法在运行时强制转换中表示递归绑定。

有没有办法重新编写代码以使其类型安全?

谢谢

最佳答案

强制转换为<? extends Copiable<?>的运行时失败(在register()调用中),因为无法声明第一个?和第二个?是相同的(未知)。

出于几乎相同的原因,asSubclass()调用会向您发出编译器警告-由于已删除了泛型,因此在运行时无法证明CopiableCopiable<AnythingInParticular>。您已经证明它是Copiable,但是尚未证明它是Copiable<Itself>

我认为您最好的期望是将警告本地化为一种混乱的方法,并添加@SuppressWarnings("unchecked")和一些注释。

您确定这将在运行时起作用吗?我感觉编译器在这里说了实话。您从Hibernate获得的类实际上是扩展了Copiable,还是只是碰巧声明了与Copiable接口匹配的方法?如果是后者,则-Java是一种强类型语言-无论如何,您的isAssignableFrom()总是将返回false。

09-15 21:30