简体   繁体   English

泛型的反思

[英]Generics in reflection

I'm creating a Class object for class Box which has a type parameter. 我正在为具有类型参数的Box创建一个Class对象。 And in the place where I get Class objects it throws an warning that class type is raw - (Class objCB = b.getClass()). 并且在我得到Class对象的地方,它发出一个警告,指出类类型是原始的-(Class objCB = b.getClass())。

My doubt is while creating a Class object for any class with type parameter why should generics come into the picture. 我的疑问是,在为具有类型参数的任何类创建Class对象时,为什么泛型应该出现在图片中。 And how to resolve the warning. 以及如何解决警告。 Below is my code 下面是我的代码

//Box Class
public class Box <T extends Comparable<T>>{

public T objA;
public T objB;      

public void set(T t1, T t2)
{
    this.objA = t1;
    this.objB = t2;
}

public int compare()
{       
return this.objA.compareTo(this.objB);      
}   

}

// Refelection class
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class Test6 {

public static void main(String[] args) throws ClassNotFoundException {

//using getClass
Box <Integer> b = new Box <Integer>();
Class objCB = b.getClass();    //warning thrown here
Method[] methods = objCB.getMethods();  
for (Method m : methods)
{
    System.out.println(m.getName());
}

System.out.println("==================");

//using class
Class objC2 = Box.class;   //warning thrown here
Field[] fields = objC2.getFields();
for (Field f : fields)
{   
    System.out.println(f.getName());
}

System.out.println("==================");
//using forName()   
Class objC3 = Class.forName("Box");  //warning thrown here
Type[] types = objC3.getTypeParameters();
for (Type t : types)
{
    System.out.println(t.toString());
}

System.out.println("==================");
//using Type()  
Class objI = Integer.TYPE;  //warning thrown here
System.out.println(objI.getName());
}
}

The Class class has a generic parameter which in general should point to the type the class represents. Class类具有一个通用参数,通常应指向该类表示的类型。 It's used to safely instantiate the object using newInstance() or getConstructor(...).newInstance() or call some other methods like cast() or getEnumConstants() . 它用于使用newInstance()getConstructor(...).newInstance()安全地实例化对象,或调用其他方法,如cast()getEnumConstants() For example, you can use without a type cast: 例如,您可以不使用类型强制转换而使用:

Integer i = Integer.class.getConstructor(int.class).newInstance(0);

In many cases it's difficult to preserve exact type argument. 在许多情况下,很难保留确切的类型参数。 For example, Object.getClass() method has return type Class<?> . 例如, Object.getClass()方法的返回类型为Class<?> On the other hand, when you are not going to instantiate the class, having Class<?> is fine. 另一方面,当您不打算实例化该类时,使用Class<?>就可以了。 So replace your raw Class with Class<?> . 因此,将您的原始Class替换为Class<?>

If you later want to change it to some specific class in safe manner, you may use asSubclass : 如果以后想要以安全的方式将其更改为某些特定的类,则可以使用asSubclass

Class<?> someClass = i.getClass();
// type check is done here: CCE will be thrown if someClass is not Integer.class
Class<? extends Integer> c = someClass.asSubclass(Integer.class);
// No type check is necessary here.
Integer ii = c.getConstructor(int.class).newInstance(0);

In any case using raw types is bad and may lead to serious problems, that's why the warning is issued. 无论如何,使用原始类型都是不好的,并且可能导致严重的问题,这就是发出警告的原因。 Avoid raw types. 避免使用原始类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM