【问题标题】:Using a generic type of a subclass within it's abstract superclass?在它的抽象超类中使用子类的泛型类型?
【发布时间】:2010-06-29 08:30:23
【问题描述】:

在我的代码中有以下抽象超类

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

还有一些子类,比如

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

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

我正在寻找一种优雅的方式,如何以通用方式在抽象类中使用子类的泛型类型(GenericTypeA、GenericTypeB、...)。

为了解决这个问题我目前定义了方法

protected abstract Class<Type> getGenericTypeClass();

在我的抽象类中实现了方法

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

在每个子类中。

是否有可能在我的抽象类中获得子类的泛型而不实现这个帮助方法?

BR,

马库斯

【问题讨论】:

    标签: java generics class abstract-class


    【解决方案1】:

    我认为这是可能的。我看到这与泛型一起用于 DAO 模式。例如 考虑类:

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

    还有你的通用类:

      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);
         }
      }
    

    您可以拥有一个类 Test1,它使用 B 类扩展 Test(它扩展 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'
         }
      }
    

    【讨论】:

    • 我不明白 Test 的构造函数中的代码究竟做了什么,但它确实有效。现在我不必再使用辅助方法了。谢谢:-)
    • 它使用反射。首先它获取类的通用超类(java.lang.reflect.Type),在我们的例子中它永远不会为空,我们知道它是一个 ParameterizedType,所以我们转换它并调用方法 getActualTypeArguents 返回一个数组实际的类型参数,例如B,类型。
    • 请注意,创建class Test2 extends Test1class TestFail&lt;T&gt; extends Test&lt;T&gt; 会破坏上述代码。
    • @ILMTitan 如果有人对可以处理几乎所有可能的继承链的代码感兴趣,您可以查看这个问题的答案:stackoverflow.com/a/60299767/4378853
    【解决方案2】:

    我不确定我是否完全理解您的问题 - &lt;Type&gt; 子类的泛型类型,即使它在抽象类中表达也是如此。例如,如果您的抽象超类定义了一个方法:

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

    如果您实例化了 ChildClassA,您将只能使用 GenericTypeA 的实例调用 augment

    现在,如果您想要一个类文字,那么您需要提供您指定的方法。但是如果你只想要泛型参数,你不需要做任何特别的事情。

    【讨论】:

    • 对不起,我真的不明白你的意思。类型由子类的泛型类型扩展。因此可以将子类的类型转换回 Type 并在抽象超类中使用它。
    • @Markus - 现在不明白你的第二句话,我认为这没有意义。您不能在任何意义上强制转换类型参数;在类定义中,它只是一个占位符,指向您实际创建对象的类型。并且子类不 extend 类型,它们为它提供了一个具体的界限。所以当AbstractClass中的方法被ChildClassA的实例调用时,typeGenericTypeA
    猜你喜欢
    • 2019-05-10
    • 1970-01-01
    • 2011-01-22
    • 2013-09-13
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多