泛型帮助程序方法与直接类强制转换



我目前是这样做的。

static <T extends Some> T doSome(Class<T> type, T obj) {
    // pre-existing legacy method
    // omitted for brevity
}
private static <T extends Some> T doSomeHelper(Class<T> type, Some obj) {
    // private!
    // only invoked from doSome(T) 
    return doSome(type, type.cast(obj));
}
@SuppressWarnings("unchecked")
static <T extends Some> T doSome(T obj) {
    return (T) doSomeHelper(obj.getClass(), obj);
}

我刚刚发现以下方法对编译器也没有问题。

@SuppressWarnings("unchecked")
public static <T extends Some> T doSome_(T obj) {
    return doSome((Class<T>) obj.getClass(), obj);
}

哪种方法更好?

第一种方法更好,因为所有类型在理论层面上都是正确的。

第二种方式,演员(Class<T>) obj.getClass()在理论上是不正确的。 obj的实际运行时类可以是T的任何子类型,因此obj.getClass()可以是Class<some subtype of T>的,这与Class<T>不兼容。由于类型擦除,强制转换实际上不会在运行时失败,但您不应编写理论上不正确的代码。

在第一种方法doSomeHelper中,type.cast(obj)不安全,因为如果obj.getClass() == Some.classtype == SubtypeOfSome.class,它将失败。 <T super Some>将是安全的(类型是 OBJ 的使用者)。

第二种方法更好,因为尽管您必须进行强制转换(因为obj.getClass()Class<? extends T> 类型),但由于它直接派生自 obj,因此可以安全地铸造Class<T>

但是,从提供的代码中看不出为什么需要重载 - 为什么不能// for brevity doSome(T obj)实现?

最新更新