Rob*_*Han 5 java generics effective-java
当我阅读有效Java项目27时,类型之间的投射UnaryFunction<Object>和UnaryFunction<T>困惑我.
interface UnaryFunction<T> {
T apply(T t);
}
public class Main {
private static final UnaryFunction<Object> IDENTITY = new UnaryFunction<Object>() {
public Object apply(Object t) {
return t;
}
};
@SuppressWarnings("unchecked")
public static <T> UnaryFunction<T> identityFunction() {
return (UnaryFunction<T>) IDENTITY;
}
public static void main(String ... args) {
UnaryFunction<A> identityA = Main.identityFunction();
A a = identityA.apply(new A());
}
}
class A {}
Run Code Online (Sandbox Code Playgroud)
为什么UnaryFunction<Object>可以投入UnaryFunction<T>?
我知道通用类型将在编译器之后被删除.因此,(UnaryFunction<T>) IDENTITY最终将(UnaryFunction<Object>) IDENTITY,这将在运行系统中工作.
但编译器不允许直接转换UnaryFunction<Object>为UnaryFunction<A>.
UnaryFunction<A> identityA = (UnaryFunction<A>)IDENTITY;
//incompatible types: UnaryFunction<java.lang.Object> cannot be converted to UnaryFunction<A>
Run Code Online (Sandbox Code Playgroud)
和之间不存在继承关系UnaryFunction<Object>和UnaryFunction<T>.那么为什么UnaryFunction<Object>可以投入UnaryFunction<T>?
所有泛型类型,没有边界 ( ... extends ...,都被认为是Object由于类型擦除。所以这个强制转换可能对T. 的某些值有效,@SuppressWarnings("unchecked")告诉编译器你在做正确的事情,所以警告被抑制。
转换为特定类型是有问题的。让我们假设您正在处理List<Object>您投射到List<A>whereA是一个类的哪个。在这种情况下, list 可能包含属于 of 的超类型元素,A因此这种强制转换是不合理的,因此编译器不允许这样做。在函数 ( UnaryFunction<Object>) 的情况下,它暗示这可以返回一个对象。假设您的代码IDENTITY = t -> new Object();在这种情况下强制转换为UnaryFunction<A>不合理,因为它返回Object. 在这种情况下,UnaryFunction<T>存在某种T满足强制转换的类型,即 whenT是 an Object。
有关此方面的一些背景阅读,请参阅:处理函数子类型的Liskov 替换原则。