有很多关于泛型的讨论以及他们在this question后面真实地做了什么,所以我们都知道 Vector<int[]>
是整数数组的向量, HashTable<String, Person>
是一个表,其键是字符串和值 Person
. 然而,让我感到困惑的是 Class<>
的用法 .
java类 Class
也应该采用模板名称,(或者我理解我应该放在那里的东西. Class
对象的全部意义在于你没有完全掌握有关对象的信息,用于反射为什么它让我指定 Class
对象将保持哪个类?我显然没有 Class
使用 Class
对象,我会使用特定的对象 .
10 回答
使用类的类的通用版本允许您(除其他外)编写类似的东西
然后你可以确定你收到的Class对象扩展
Collection
,这个类的实例将是(至少)一个Collection .我们所知道的是“任何类的所有实例都共享该类类型的java.lang.Class对象”
例如)
然后
a.getClass() == b.getClass()
是真的 .现在假设
没有泛型,下面是可能的 .
但现在这是错的..?
例如
public void printStudentClassInfo(Class studentClassRef) {}
可以用Teacher.class
调用使用泛型可以避免这种情况 .
现在什么是T ?? T是类型参数(也称为类型变量);由尖括号(<>)分隔,跟在类名后面 .
T只是一个符号,就像在编写类文件时声明的变量名(可以是任何名称) . 后来T将被替换
初始化期间的有效类名称(
HashMap<String> map = new HashMap<String>();
)例如)
class name<T1, T2, ..., Tn>
所以
Class<T>
表示特定类类型'T
'的类对象 .假设您的类方法必须使用下面的未知类型参数
这里T可以用作
String
类型 CarNameOR T可以用作
Integer
类型 modelNumber ,OR T可以用作
Object
类型 valid car instance .现在,上面是简单的POJO,它可以在运行时以不同的方式使用 .
集合例如List,Set,Hashmap是根据T的声明使用不同对象的最佳示例,但是一旦我们将T声明为String
例如
HashMap<String> map = new HashMap<String>();
然后它只接受String Class实例对象 .Generic Methods
通用方法是引入其自己的类型参数的方法 . 这类似于声明泛型类型,但类型参数的范围仅限于声明它的方法 . 允许使用静态和非静态泛型方法,以及泛型类构造函数 .
泛型方法的语法包括一个类型参数,在尖括号内,并出现在方法的返回类型之前 . 对于泛型方法,类型参数部分必须出现在方法的返回类型之前 .
这里
<K, V, Z, Y>
是方法参数中使用的类型声明,它应该在返回类型之前boolean
这里 .在下面;类型声明
<T>
在方法级别不是必需的,因为它已在类级别声明 .但是下面的错误是因为类级别的参数K,V,Z和Y不能在静态上下文中使用(这里是静态方法) .
OTHER VALID SCENARIOS ARE
最后,静态方法总是需要显式
<T>
声明;它不会从 classClass<T>
派生 . 这是因为类级别T与实例绑定 .另请阅读Restrictions on Generics
从Java文档:
[...]更令人惊讶的是, class 已经普及 . 类文本现在用作类型标记,提供运行时和编译时类型信息 . 这样可以在新的AnnotatedElement接口中使用getAnnotation方法示例的静态工厂样式:
这是一种通用方法 . 它从参数中推断出其类型参数T的值,并返回一个适当的T实例,如下面的代码片段所示:
在泛型之前,您必须将结果转换为Author . 此外,您无法让编译器检查实际参数是否表示Annotation的子类 . [...]
好吧,我从来没有使用过这种东西 . 任何人?
我在创建服务注册表查找时发现
class<T>
很有用 . 例如 .正如其他答案所指出的那样,为什么这个
class
有很多很好的理由制作通用 . 但是,有很多次你无法知道Class<T>
使用的泛型类型 . 在这些情况下,您可以简单地忽略黄色日食警告,或者您可以使用Class<?>
......我就是这样做的;)继@Kire Haglin的回答之后,_2485554中可以看到另一个泛型方法示例:
这允许
unmarshal
返回任意JAXB内容树类型的文档 .您经常要使用带有
Class
的通配符 . 例如,Class<? extends JComponent>
将允许您指定该类是JComponent
的某个子类 . 如果您从Class.forName
检索了Class
实例,则可以在尝试构建实例之前使用Class.asSubclass
进行强制转换 .换句话说,Class的通用版本(
Class<T>
)允许编写下面的通用函数 .一开始很困惑 . 但它有助于以下情况:
只需使用牛肉类: