简体   繁体   中英

Using a generic type of a subclass within it's abstract superclass?

Within my code a have the following abstract superclass

public abstract class AbstractClass<Type extends A> {...}

and some child classes like

public class ChildClassA extends AbstractClass<GenericTypeA> {...}

public class ChildClassB extends AbstractClass<GenericTypeB> {...}

I'm searching for an elegant way how I can use the generic type of the child classes (GenericTypeA, GenericTypeB, ...) inside the abstract class in a generic way.

To solve this problem I currently defined the method

protected abstract Class<Type> getGenericTypeClass();

in my abstract class and implemented the method

@Override
protected Class<GenericType> getGenericTypeClass() {
    return GenericType.class;
}

in every child class.

Is it possible to get the generic type of the child classes in my abstract class without implementing this helper method?

BR,

Markus

I think its possible. I saw this was being used in the DAO patterns along with generics. eg Consider classes:

public class A {}
public class B extends A {}

And your generic class:

  import java.lang.reflect.ParameterizedType;
  public abstract class Test<T extends A> {

     private Class<T> theType;

     public Test()  {
        theType = (Class<T>) (
               (ParameterizedType) getClass().getGenericSuperclass())
              .getActualTypeArguments()[0];
     }

     // this method will always return the type that extends class "A"
     public Class<T> getTheType()   {
        return theType;
     }

     public void printType() {
        Class<T> clazz = getTheType();
        System.out.println(clazz);
     }
  }

You can have a class Test1 that extends Test with class B (it extends A)

  public class Test1 extends Test<B>  {

     public static void main(String[] args) {
        Test1 t = new Test1();

        Class<B> clazz = t.getTheType();

        System.out.println(clazz); // will print 'class B'
        System.out.println(printType()); // will print 'class B'
     }
  }

I'm not sure I fully understand your question - <Type> is the generic type of the subclass, even when it's being expressed in the abstract class. For example, if your abstract superclass defines a method:

public void augment(Type entity) {
   ...
}

and you instantiate a ChildClassA , you'll only be able to call augment with an instance of GenericTypeA .

Now if you want a class literal, then you'll need to provide the method as you indicated. But if you just want the generic parameter, you don't need to do anything special.

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