类Class <T>的通用性质是什么意思?什么是T?

Tim*_*Tim 41 java generics reflection class

在集合方面,我理解泛型.但是在Class<T>课堂上它意味着什么呢?实例化Class对象时,只有一个对象.那为什么T参数呢?这是什么规定的?为什么有必要(如果是)?

das*_*ght 48

<T>已添加类型参数java.lang.Class以启用一个特定的习惯用法1 - 将Class对象用作类型安全的对象工厂.本质上,添加<T>允许您以类型安全的方式实例化类,如下所示:

T instance = myClass.newInstance();
Run Code Online (Sandbox Code Playgroud)

类型参数<T>表示类本身,通过存储Class<T>在泛型类中或将其作为参数传递给泛型方法,可以避免类型擦除的令人不快的影响.请注意,T它本身不足以完成这个任务2:T被删除的类型,所以它变成java.lang.Object了引擎盖.

这是一个典型的例子,其中<T>类的参数变得重要.在下面的示例中,Java编译器能够确保类型安全,允许您从SQL字符串和实例中生成类型集合Class<T>.请注意,该类用作工厂,并且可以在编译时验证其类型安全性:

public static <T> Collection<T> select(Class<T> c, String sqlStatement) {
    Collection<T> result = new ArrayList<T>();
    /* run sql query using jdbc */
    for ( /* iterate over jdbc results */ ) {
        T item = c.newInstance();
        /* use re?ection and set all of item’s ?elds from sql results */
        result.add(item);
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

由于Java会删除type参数,使其成为java.lang.Object指定为泛型上限的类或类,因此访问方法Class<T>内的对象非常重要select.由于newInstance返回类型的对象<T>,编译器可以执行类型检查,从而消除了强制转换.


1 SUN Oracle发表了一篇很好的文章来解释这一切.
2这与没有类型擦除的泛型的实现不同,例如.NET中的类型擦除.
3 Oracle的Java Generics教程.

  • 没有它,`instance`将是类`Object`,你需要进行类型转换以使其有用. (3认同)

MvG*_*MvG 8

dasblinkenlight答案已经证明了这个参数的主要用途之一.还有一个我认为相关的方面:使用该参数,您可以限制要在给定位置传递的类的类型.所以,例如

Class<? extends Number> cls
Run Code Online (Sandbox Code Playgroud)

表示cls可以是实现该Number接口的任何类.这有助于在编译时捕获某些错误,并使类参数要求更加明确.

或许可以与没有泛型的情况进行比较

// Java ?5 with generics    // Java <5 style without generics
Class<? extends Foo> c;     Class c;
Foo t1 = c.newInstance();   Foo t1 = (Foo)c.newInstance();
Object obj;                 Object obj;
Foo t2 = c.cast(obj);       Foo t2 = (Foo)c.cast(obj);
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,没有T作为参数需要一些显式的强制转换,因为相应的方法必须返回Object而不是T.如果Foo它本身是泛型类型参数,那么所有这些强制转换都将被取消选中,从而产生一系列编译器警告.您可以抑制它们,但核心问题仍然存在:除非您正确使用type参数,否则编译器无法检查这些强制转换的有效性.