如何将此对象转换为泛型类型?

ham*_*uki 11 java generics casting effective-java

我的理解是泛型类型是不变的,所以如果我们B作为子类型A,则List<B>与之无关List<A>.因此,铸造将无法正常工作的List<A>List<B>.

从Effective Java Third Edition我们有这段代码:

// Generic singleton factory pattern
private static UnaryOperator<Object> IDENTIFY_FN = (t) -> t;

@SuppressWarnings("unchecked")
public static <T> UnaryOperator<T> identifyFunction() {
    return (UnaryOperator<T>) IDENTIFY_FN; //OK But how, why?
}

public static void main(String[] args) {
    String[] strings = {"a", "b", "c"};
    UnaryOperator<String> sameString = identifyFunction();
    for (String s : strings) {
        System.out.println(sameString.apply(s));
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里很困惑.我们已经投下IDENTIFY_FN,其类型UnaryOperator<Object>,对UnaryOperator<T>,它有另一种类型的参数.

当类型擦除发生时String是Object的子类型,但据我所知,UnaryOperator<String>它不是一个子类型UnaryOperator<Object>.

对象和T以某种方式相关吗?在这种情况下,铸造如何成功?

Mic*_*ael 2

泛型在运行时不存在。在运行时,每个 UnaryOperator<T>都是一个UnaryOperator<Object>. 为了在编译时安抚编译器,必须进行强制转换。在运行时它是没有意义的。

  • 问题是为什么强制转换在编译时是合法的。像“(UnityOperator&lt;String&gt;) IDENTITY_FN”这样的直接转换**不**是合法的。 (4认同)
  • 我认为这正是提问者不确定的地方。当编译器知道强制转换将失败时,编译器会发出抱怨,但当它知道强制转换可能会失败时,则不会发出抱怨,就像在本例中一样。 (2认同)