泛型方法参数的getClass()强制转换安全

时间:2018-11-15 09:24:04

标签: java generics

这个演员安全吗?

private <T> void foo(T value) {
    final Class<T> aClass = (Class<T>) value.getClass();
} 

是否存在更优雅的方法?

是否可以避免未经检查的投放警告?

1 个答案:

答案 0 :(得分:2)

您可以禁止编译器警告。参见What is SuppressWarnings ("unchecked") in Java?

编译器出于某种原因警告您。 value可以包含T某些子类型的对象,并且Class<Parent>Class<Child>之间存在重要区别。就您而言,您可以看到您所做的任何事情都不是不安全的,但是编译器只是遵循规则。

想象一下,如果方法略有不同,并且有一种方法可以获取T类型的另一个值:

<T> void foo(T a, T b) {
    final Class<T> aClass = (Class<T>) a.getClass();

    // What can go wrong?  casting T to T
    T c = aClass.cast(b);
}

// but what if the two parameters are of different classes at runtime
foo(5, 5.5);   // ClassCastException!

或者如果我们允许Class<T>作为返回值转义怎么办:

<T> Class<T> foo(T val) {
    final Class<T> aClass = (Class<T>) val.getClass();
    return aClass;
}

// uhoh is declared as Class<Number> but contains Class<Integer> at runtime
Class<Number> uhoh = foo(5);

// Ok to cast Double to Number but not to Integer
Number num = uhoh.cast(5.5);  // ClassCastException!