猿问

如何在Java中使用Class <T>?

在这个问题上,对泛型及其背后的作用进行了很好的讨论,因此我们都知道泛型Vector<int[]>是整数数组的向量,并且HashTable<String, Person>是一个表,其键是字符串和值Persons。但是,让我感到困扰的是的用法Class<>。


Java类Class应该也采用一个模板名称,(否则,Eclipse中的黄色下划线告诉我)。我不明白该放什么。在整点Class的对象是当你不完全具备有关对象的信息,进行反思和这样的。为什么要让我指定Class对象将容纳哪个类?我显然不知道,或者我不会使用该Class对象,而是使用特定的对象。


慕容森
浏览 6768回答 3
3回答

慕妹3146593

使用Class的通用版本,Class可以让您编写诸如Class<? extends Collection> someCollectionClass = someMethod();然后,您可以确保收到的Class对象扩展了Collection,并且该类的实例将(至少)是Collection。

largeQ

我们所知道的是“ 任何类的所有实例共享该类类型的相同java.lang.Class对象 ”例如)Student a = new Student();Student b = new Student();那a.getClass() == b.getClass()是真的。现在假设Teacher t = new Teacher();没有泛型,下面是可能的。Class studentClassRef = t.getClass();但这是错误的..?例如)public void printStudentClassInfo(Class studentClassRef) {}可以用Teacher.class使用泛型可以避免这种情况。Class<Student> studentClassRef = t.getClass(); //Compilation error.现在什么是T ?? T是类型参数(也称为类型变量);用尖括号(<>)分隔,在类名之后。T只是一个符号,就像在编写类文件期间声明的变量名(可以是任何名称)一样。稍后,在初始化(HashMap<String> map = new HashMap<String>();)时将用有效的类名替换T例如) class name<T1, T2, ..., Tn>因此Class<T>表示特定类类型为' T' 的类对象。假设您的类方法必须使用未知的类型参数,如下所示/**&nbsp;* Generic version of the Car class.&nbsp;* @param <T> the type of the value&nbsp;*/public class Car<T> {&nbsp; &nbsp; // T stands for "Type"&nbsp; &nbsp; private T t;&nbsp; &nbsp; public void set(T t) { this.t = t; }&nbsp; &nbsp; public T get() { return t; }}在这里T可以String用作CarName的类型OR T可以用作modelNumber的Integer类型,OR T可以用作有效的汽车实例的Object类型。现在,上面是简单的POJO,可以在运行时以不同的方式使用它。集合(例如List,Set,Hashmap)是最好的示例,它们将根据T的声明与不同的对象一起工作,但是一旦我们将T声明为String(例如)HashMap<String> map = new HashMap<String>();,则它将仅接受String类实例对象。通用方法泛型方法是引入自己的类型参数的方法。这类似于声明泛型类型,但是类型参数的范围仅限于声明它的方法。允许使用静态和非静态通用方法,以及通用类构造函数。通用方法的语法包括类型参数,尖括号内,并且出现在方法的返回类型之前。对于泛型方法,类型参数部分必须出现在方法的返回类型之前。&nbsp;class Util {&nbsp; &nbsp; // Generic static method&nbsp; &nbsp; public static <K, V, Z, Y> boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {&nbsp; &nbsp; &nbsp; &nbsp; return p1.getKey().equals(p2.getKey()) &&&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p1.getValue().equals(p2.getValue());&nbsp; &nbsp; }}&nbsp;class Pair<K, V> {&nbsp; &nbsp; private K key;&nbsp; &nbsp; private V value;}这<K, V, Z, Y>是方法参数中使用的类型声明,该声明应在boolean此处的返回类型之前。在下面;<T>在方法级别不需要类型声明,因为它已经在类级别声明了。class MyClass<T> {&nbsp; &nbsp;private&nbsp; T myMethod(T a){&nbsp; &nbsp; &nbsp; &nbsp;return&nbsp; a;&nbsp; &nbsp;}}但是下面是错误的,因为类级别的类型参数K,V,Z和Y不能在静态上下文中使用(此处为静态方法)。class Util <K, V, Z, Y>{&nbsp; &nbsp; // Generic static method&nbsp; &nbsp; public static&nbsp; boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {&nbsp; &nbsp; &nbsp; &nbsp; return p1.getKey().equals(p2.getKey()) &&&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p1.getValue().equals(p2.getValue());&nbsp; &nbsp; }}其他有效场景class MyClass<T> {&nbsp; &nbsp; &nbsp; &nbsp; //Type declaration <T> already done at class level&nbsp; &nbsp; &nbsp; &nbsp; private&nbsp; T myMethod(T a){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; a;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; //<T> is overriding the T declared at Class level;&nbsp; &nbsp; &nbsp; &nbsp; //So There is no ClassCastException though a is not the type of T declared at MyClass<T>.&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; private <T> T myMethod1(Object a){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (T) a;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; //Runtime ClassCastException will be thrown if a is not the type T (MyClass<T>).&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; private T myMethod1(Object a){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (T) a;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // No ClassCastException&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // MyClass<String> obj= new MyClass<String>();&nbsp; &nbsp; &nbsp; &nbsp; // obj.myMethod2(Integer.valueOf("1"));&nbsp; &nbsp; &nbsp; &nbsp; // Since type T is redefined at this method level.&nbsp; &nbsp; &nbsp; &nbsp; private <T> T myMethod2(T a){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; a;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // No ClassCastException for the below&nbsp; &nbsp; &nbsp; &nbsp; // MyClass<String> o= new MyClass<String>();&nbsp; &nbsp; &nbsp; &nbsp; // o.myMethod3(Integer.valueOf("1").getClass())&nbsp; &nbsp; &nbsp; &nbsp; // Since <T> is undefined within this method;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // And MyClass<T> don't have impact here&nbsp; &nbsp; &nbsp; &nbsp; private <T> T myMethod3(Class a){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (T) a;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // ClassCastException for o.myMethod3(Integer.valueOf("1").getClass())&nbsp; &nbsp; &nbsp; &nbsp; // Should be o.myMethod3(String.valueOf("1").getClass())&nbsp; &nbsp; private&nbsp; T myMethod3(Class a){&nbsp; &nbsp; &nbsp; &nbsp; return (T) a;&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Class<T> a :: a is Class object of type T&nbsp; &nbsp; &nbsp; &nbsp; //<T> is overriding of class level type declaration;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; private <T> Class<T> myMethod4(Class<T> a){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; a;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }最后,静态方法总是需要显式<T>声明。它不会从课堂上衍生出来Class<T>。这是因为类级别T与实例绑定。

慕婉清6462132

从Java文档中:[...]更令人惊讶的是,类Class已被泛化。现在,类文字可以用作类型令牌,同时提供运行时和编译时类型信息。这将启用一种新的AnnotatedElement接口中的getAnnotation方法示例的静态工厂样式:<T extends Annotation> T getAnnotation(Class<T> annotationType);&nbsp;这是一种通用方法。它从其参数推断其类型参数T的值,并返回T的适当实例,如以下代码段所示:Author a = Othello.class.getAnnotation(Author.class);在使用泛型之前,您必须将结果强制转换为Author。另外,您将无法使编译器检查实际参数是否表示Annotation的子类。[...]好吧,我从来没有用过这种东西。任何人?
随时随地看视频慕课网APP

相关分类

Java
我要回答