我有一个接口,可以确保对象可以复制自己:
public interface Duplicable<T extends Duplicable<T>> {
public T duplicate();
}
我现在有
class X implements Duplicable<X>
但我也有一个扩展X.的类Y
这不是问题,直到我需要另一个通用类:
public class DoStuffWithDuplicable<T extends Duplicable<T>>
我不能使用Y使用DostuffWithDupliable的通用版本,因为它不实现Duplicable<Y>
,而是实现Duplicable<X>
,因为它继承了X.
所以我尝试了
public class DoStuffWithDuplicable<T extends Duplicable<? super T>>
但这意味着以后会引入不安全的铸造
(T) obj.duplicate()
在代码体中。此外,类参数更复杂,类的用法更难理解。有什么办法解决这个问题吗?
我可能没有完全理解你的问题,但我会试一试。
首先,为什么你有一个这样扩展自己的接口?
你可以试试这个:
public interface Duplicable<T> {
public T duplicate();
}
然后,当你使用另一个类时,你希望通用参数是可重复的,你可以这样做:
public class X<T extends Duplicable<T>> {
code...
}
现在,当您从X继承时,子类中的任何通用组件都必须是可复制的。
在Java中不可能做到这一点。
假设您对Y类型的对象调用obj.duplicate()。那么类型系统只能确保它将返回X类型的对象,因为Y实现了duplicate<X>。
但是您可以创建一个DoStuffWithDuplicable<X>并将Y个对象传递给它。
DoStuffWithDuplicable<X> blub = new DoStuffWithDuplicable<X>();
Y y = (Y) blub.doStuff(new Y());
对于返回值,库的客户端可以只使用安全类型转换,因为他可能知道具体的类型。
另一种选择是在库中使用不安全的强制转换,并手动检查类型:
class DoStuffWithDuplicable<T extends Duplicable<? super T>> {
T doStuff(T obj) {
@SuppressWarnings("unchecked")
T t = (T) obj.duplicate();
if (!t.getClass().equals(obj.getClass()))
throw new ClassCastException("...");
return t;
}
}