类 Class<T> 的泛型性质是什么意思?什么是 T?

2022-08-31 21:01:35

当涉及到集合时,我了解泛型。但是,对于类来说,这意味着什么呢?实例化对象时,只有一个对象。那么为什么是参数呢?它指定了什么?为什么有必要(如果有的话)?Class<T>ClassT


答案 1

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

T instance = myClass.newInstance();

Type 参数表示类本身,使您能够通过存储在泛型类中或将其作为参数传递给泛型方法来避免类型擦除的令人不快的影响。请注意,本身不足以完成此任务2:的类型被擦除,因此它变成了引擎盖下。<T>Class<T>TTjava.lang.Object

下面是一个经典示例,其中类的参数变得很重要。在下面的示例中,Java 编译器能够确保类型安全,允许您从 SQL 字符串和 的实例生成类型化集合。请注意,该类用作工厂,并且可以在编译时验证其类型安全性:<T>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 reflection and set all of item’s fields from sql results */
        result.add(item);
    }
    return result;
}

由于 Java 会擦除类型参数,使其成为指定为泛型上限的类,因此访问方法中的对象非常重要。由于返回一个类型的对象,编译器可以执行类型检查,消除强制转换。java.lang.ObjectClass<T>selectnewInstance<T>


1SUN Oracle发表了一篇很好的文章来解释这一切
2 这与不带类型擦除的泛型的实现(如 .NET 中的泛型)不同。
3Oracle 的 Java Generics tutorial

答案 2

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

Class<? extends Number> cls

意味着可以是实现接口的任何类。这可以帮助在编译时捕获某些错误,并使类参数要求更加明确。clsNumber

也许与没有泛型的情况进行比较是有序的

// 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);

如您所见,不具有作为参数将需要许多显式强制转换,因为相应的方法必须返回而不是 。如果本身是泛型类型参数,则所有这些强制转换都将被取消选中,从而导致一系列编译器警告。您可以禁止显示它们,但核心问题仍然存在:除非您正确使用 type 参数,否则编译器无法检查这些强制转换的有效性。TObjectTFoo