为什么UnaryFunction <Object>可以转换为UnaryFunction <T>?

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>

Sum*_*ena 5

所有泛型类型,没有边界 ( ... 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 替换原则