5 Replies Latest reply: Jun 18, 2010 10:54 AM by 843793 RSS

    Determine class type of Generic Parameter (not via getGenericSuperclass()!)

    843793
      I need to know the class type of a generic Parameter. Please imagine this class:
      class MyGenericClass<T>
      {
      ...
      }
      In cases where other classes derived from MyClass and defined the generic parameter (like MyDerivedClass extends MyGenericClass<String>),
      this snippets works just fine:
      (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
      But now I have no inheritance but the definition of the type parameter via instantiation:
      MyGenericClass<String> entity = new MyGenericClass<String>();
      The method "getGenericSuperclass()" does not suit my needs because it does not target the actual class. Nor can "getTypeParameters() " help me...
      After countless trying to retrieved the type information, I still have no clue how to determine for that case that (in my example) the type parameter
      is a 'String'.

      Does anyone know the solution?
        • 1. Re: Determine class type of Generic Parameter (not via getGenericSuperclass()!)
          843793
          There is no solution. "String" in your solution is not reified: it is [completely erased|http://java.sun.com/docs/books/tutorial/java/generics/erasure.html] by runtime.

          But I doubt you actually "need" to know this at runtime. When a newbie (no offence intended, but developers with some generics experience know about erasure!) says they need the type parameter at runtime, it's usually a symptom of a bad design decision. Why not let us know what you're trying to accomplish and why, so we can help you with a more suitable solution?
          • 2. Re: Determine class type of Generic Parameter (not via getGenericSuperclass()!)
            843793
            Thank you for your answer. My task is to have a class which exports data via JAXB to a file. This exporter has to work with different JAXB-annotated classes,
            but does in general the same (except some configurable parameters). The only real difference ist the line for instancing the context:
            JAXBContext context = JAXBContext.newInstance(exportClassType);
            Sure I could pass the class type itself as parameter to be stored in 'exportClassType'. But I only tried to adapt the idea used e.g. in Generic DAOs
            as descibed here: [http://community.jboss.org/wiki/GenericDataAccessObjects]. The big difference is, that in the Generic DAO example the typed
            information is available within the class definition ..

            Besides that I am open for any other suggestion!
            • 3. Re: Determine class type of Generic Parameter (not via getGenericSuperclass()!)
              843793
              Serethos_0 wrote:
              Sure I could pass the class type itself as parameter to be stored in 'exportClassType'. But I only tried to adapt the idea used e.g. in Generic DAOs
              as descibed here: [http://community.jboss.org/wiki/GenericDataAccessObjects]. The big difference is, that in the Generic DAO example the typed
              information is available within the class definition ..

              Besides that I am open for any other suggestion!
              I would recommend passing around the Class object as you say.

              Some might suggest that you make MyGenericClass abstract, forcing any instantiation to be like this:
              MyGenericClass<String> entity = new MyGenericClass<String>() {};
              That would indeed cause the String type parameter to be available at runtime, since you're creating an anonymous inner class. But it leads to a convoluted and extremely statically expensive instantiation pattern. Using the class object is a better solution IMO.
              • 4. Re: Determine class type of Generic Parameter (not via getGenericSuperclass()!)
                843793
                It is now my current implementation to inject the class type. But at a fast glance it looks very redundant to use a generic type (to have typed
                methods for the exporting) and to use the class type as parameter.

                Thank you for the discussion.
                • 5. Re: Determine class type of Generic Parameter (not via getGenericSuperclass()!)
                  843793
                  Serethos_0 wrote:
                  It is now my current implementation to inject the class type. But at a fast glance it looks very redundant to use a generic type (to have typed
                  methods for the exporting) and to use the class type as parameter.
                  You just have to separate them in your mind. One is for compile-time type safety, the other for run-time type information.

                  Just make sure to correlate the type and the class. Like this:
                  public MyGenericClass<T> {
                  
                      public MyGenericClass(Class<T> type) { //or, depending on requirements, Class<? extends T>
                      }
                  }
                  Or better yet, with a factory method:
                  public MyGenericClass<T> {
                     private MyGenericClass(Class<T> type) {
                     }
                  
                     public static <T> MyGenericClass<T> forType(Class<T> type) {
                        return new MyGenericClass(type);   
                     }
                  }