简体   繁体   中英

Java create objects of generic type with unknown in compilation type parameter

I have generic class :

class Field<T> { }

And some other class (whose type I know only at runtime) with many get methods for example :

   class A{
      public Date getDate();
      public String getName();
      public Integer getNumber();
   }

I want to create instances of class Field for all get methods, with T equals to return type of these get methods. For this example Field<Date> , Field<String> , Field<Integer> .

Can anybody help?

You use reflection typically for things that you only know at run-time. Generics information is erased at compile-time. So, while there are cases where you can mix the two, it is not common.

I want to create instances of class Field for all get methods, with T equals to return type of these get methods. For this example Field, Field, Field.

To answer your question literally:

Field<Date> dateField = new Field<Date>();
Field<String> nameField = new Field<String>();
Field<Integer> numberField = new Field<Integer>();
class Field<T> { 
    T value;
    Field(T value) {this.value = value;}
}


class A{
   Date date;
   public Field<Date> getDate() {
       return new Field<Date>(date);
   }

   //etc....
}

Think of generics as compiler annotations instead of actual run-time type checks. The compiled code will simply have static casts, and not perform any generic type checking at all. The generics feature was just sort of tacked on to the compiler to provide runtime compatibility with older JVMs, using what Sun referred to as, "Type Erasure". Here is some good reading about it:

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

在这种情况下,我不相信你可以创建泛型类型的Field,因为在编译时检查泛型,而你只能在运行时获得(通过反射)类A的声明方法的返回类型。

To obtain the getters, consider using introspection rather than reflection : it is intended for this purpose!

Here is a code to automatically obtain the getters. Beware, you also get "getClass()" getter!

for(PropertyDescriptor descriptor :Introspector.getBeanInfo(A.class).getPropertyDescriptors()){
  System.out.println("Getter method :" + descriptor.getReadMethod());
  System.out.println("Return type : " + descriptor.getReadMethod().getReturnType());
  Class<?> c=descriptor.getReadMethod().getReturnType();
}

}

Output :

Getter method :public final native java.lang.Class java.lang.Object.getClass()
Return type : class java.lang.Class
Getter method :public java.util.Date A.getDate()
Return type : class java.util.Date
Getter method :public java.lang.String A.getName()
Return type : class java.lang.String
Getter method :public java.lang.Integer A.getNumber()
Return type : class java.lang.Integer

Then, you can easily create a Field for each of those getters. For the generic type, it does not really make sense at runtime but it is still possible to use this in a code generator...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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