我定义了一个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()
调用会向您发出编译器警告-由于已删除了泛型,因此在运行时无法证明Copiable
是Copiable<AnythingInParticular>
。您已经证明它是Copiable
,但是尚未证明它是Copiable<Itself>
。
我认为您最好的期望是将警告本地化为一种混乱的方法,并添加@SuppressWarnings("unchecked")
和一些注释。
您确定这将在运行时起作用吗?我感觉编译器在这里说了实话。您从Hibernate获得的类实际上是扩展了Copiable
,还是只是碰巧声明了与Copiable
接口匹配的方法?如果是后者,则-Java是一种强类型语言-无论如何,您的isAssignableFrom()
总是将返回false。