为什么 UnaryFunction<Object> 可以转换为 UnaryFunction<T>?
Why UnaryFunction<Object> can be casted to UnaryFunction<T>?
当我阅读Effective Java第27条时,UnaryFunction<Object>
和[=15之间的类型转换=] 把我弄糊涂了。
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 {}
为什么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>
并且UnaryFunction<Object>
和UnaryFunction<T>
之间没有继承关系。那么为什么UnaryFunction<Object>
可以转换为UnaryFunction<T>
?
由于类型擦除,所有没有边界的泛型类型 (... extends ...
都被视为 Object
。因此此转换可能对 T
的某些值有效。@SuppressWarnings("unchecked")
告诉编译器你做的是正确的,所以警告被抑制了。
转换为特定类型存在问题。假设您正在处理 List<Object>
,您将其转换为 List<A>
,其中 A
是 class。在这种情况下,列表中的元素可能是 A
的超类型,因此这种转换是不合理的,因此编译器不允许这样做。在函数 (UnaryFunction<Object>
) 的情况下,暗示这可以 return 一个对象。假设您的代码是 IDENTITY = t -> new Object();
,在这种情况下转换为 UnaryFunction<A>
是不合理的,因为它 return 是 Object
。在 UnaryFunction<T>
的情况下,有一些类型 T
满足转换,也就是说,当 T
是 Object
.
有关这方面的一些背景阅读,请参阅:Liskov substitution principle 处理函数的子类型。
当我阅读Effective Java第27条时,UnaryFunction<Object>
和[=15之间的类型转换=] 把我弄糊涂了。
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 {}
为什么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>
并且UnaryFunction<Object>
和UnaryFunction<T>
之间没有继承关系。那么为什么UnaryFunction<Object>
可以转换为UnaryFunction<T>
?
由于类型擦除,所有没有边界的泛型类型 (... extends ...
都被视为 Object
。因此此转换可能对 T
的某些值有效。@SuppressWarnings("unchecked")
告诉编译器你做的是正确的,所以警告被抑制了。
转换为特定类型存在问题。假设您正在处理 List<Object>
,您将其转换为 List<A>
,其中 A
是 class。在这种情况下,列表中的元素可能是 A
的超类型,因此这种转换是不合理的,因此编译器不允许这样做。在函数 (UnaryFunction<Object>
) 的情况下,暗示这可以 return 一个对象。假设您的代码是 IDENTITY = t -> new Object();
,在这种情况下转换为 UnaryFunction<A>
是不合理的,因为它 return 是 Object
。在 UnaryFunction<T>
的情况下,有一些类型 T
满足转换,也就是说,当 T
是 Object
.
有关这方面的一些背景阅读,请参阅:Liskov substitution principle 处理函数的子类型。