Java 类的泛型性质意味着什么?什么是T?

Java 类的泛型性质意味着什么?什么是T?,java,class,generics,reflection,Java,Class,Generics,Reflection,当涉及到集合时,我理解泛型。但这对班级来说意味着什么呢?实例化类对象时,只有一个对象。那么为什么选择T参数呢?具体是什么?如果是,为什么有必要呢?类型参数已添加到java.lang.Class中,以启用一个特定的习惯用法1-将类对象用作类型安全的对象工厂。本质上,添加允许您以类型安全的方式实例化类,如下所示: T instance = myClass.newInstance(); 类型参数表示类本身,通过将类存储在泛型类中或将其作为参数传递给泛型方法,可以避免类型擦除带来的不愉快影响。请注意,

当涉及到集合时,我理解泛型。但这对班级来说意味着什么呢?实例化类对象时,只有一个对象。那么为什么选择T参数呢?具体是什么?如果是,为什么有必要呢?

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

T instance = myClass.newInstance();
类型参数表示类本身,通过将类存储在泛型类中或将其作为参数传递给泛型方法,可以避免类型擦除带来的不愉快影响。请注意,T本身不足以完成此任务2:T的类型被擦除,因此它在引擎盖下成为java.lang.Object

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

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.Object或指定为泛型的类,因此访问select方法中的class对象非常重要。由于newInstance返回类型为的对象,编译器可以执行类型检查,从而消除强制转换

1 SUN Oracle已发布。 2这与没有类型擦除的泛型实现不同,例如.NET中的泛型实现。
3由Oracle提供。

在类类型中使用泛型是定义类类型的首要方法。如果我有'Class obj',我的对象obj只能容纳Charsequence的子对象。
这是一个可选参数。如果我不需要特定类型的类,我通常会在Eclipse IDE中加一个“?”,以避免出现警告。

在Java中,只有一个元类:class。每个类型只有一个实例用于表示类和接口,因此类中的T表示类的当前实例所表示的类或接口的类型。

已经演示了此参数的主要用途之一。还有一个方面我认为是相关的:使用该参数,您可以限制要在给定位置传递的类。例如

Class<? extends Number> cls

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

这个答案是合适的@达斯宾莱特:对不起,我不太明白。你能不能给我一个例子,说明你是怎么做的以及为什么要这样做的?如果没有这个例子,实例将是类对象,你需要进行类型转换以使其有用。类型擦除只是为了支持从一开始就没有设计到语言中的东西吗?或者它比非类型擦除泛型有一些真正的好处吗抱歉,如果这是一个愚蠢的问题,我对C风格不是很熟悉generics@ycomp类型擦除是一种将泛型实现完全保留在编译阶段的技术,而不会溢出到JVM中。另一方面,C的方法将泛型的实现在编译器和CLR C对应的JVM中进行分割。@Redandwhite,如果您可以通过单击我问题旁边的漂亮的向上箭头来表达这种“+1”的感觉,我将非常高兴,非常感谢-顺便问一下,Java反射在现实生活中有多常见?这是泛型中我唯一不理解的部分。在将近一年的专业Java开发中,我还没有发现需要反射,尽管我一直在集合中使用泛型time@Redandwhite,反射被相当多的框架使用,用于TAK,如序列化(如jaxb)、依赖项注入(如guice)、方法枚举(如junit)等。因此,作为应用程序开发人员,不使用它们是正常的。作为库开发人员,它取决于库。请注意,对于运行时类型检查的容器,您还需要正确类型的类参数,如和friends提供的。除了“因此”之外,你说的都是对的。您可以很容易地拥有一个带有表示类型的实例的元类,而不必让该类成为泛型。在泛型出现之前,它就是这样工作的。
// 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);