【问题标题】:Getting an instance of a parameterized class in Java [duplicate]在Java中获取参数化类的实例[重复]
【发布时间】:2013-06-21 13:50:57
【问题描述】:

我有这两门课

abstract class A
{
//some abstract methods and variables
}

class B<E extends A>
{
}

现在在 B 的方法中,我想获取 E 的虚拟实例。怎么做? 可以吗-

E temp = (E)(new Object());

我可以控制类定义,因此它们很灵活。

【问题讨论】:

    标签: java generics inheritance


    【解决方案1】:

    您需要将工厂对象(或实例)传入B 的构造函数。无法指定泛型类型参数具有特定的构造函数,并且静态类型在运行时不可用。

    (您可以使用E temp = (E)new A() { }; 伪造一个可分辨的值,但这很狡猾。一些集合代码仅对数组执行类似的操作。)

    【讨论】:

      【解决方案2】:

      您有 2 个解决方案:

      • 如果E 有一个无参数构造函数,您可以使用反射来构建一个。
      • 你可以做一个抽象方法abstract E buildE();

      对于 first 解决方案,您必须将类作为构造函数的参数传递:

      class B<E extends A>{
      
        public B(Class<E> clazz){
          //Create instance of E:
          E e=clazz.newInstance();
        }
      }
      

      对于第二种的解决方案,意味着B类有一个抽象方法来构建对象(它或多或少相当于传递一个工厂):

      public class B<E extends A>{
      
        public abstract E buildE();
      
        private void foo(){
          E e = buildE();
          //Do generic stuff with E
        }
      
      }
      

      这样,如果你创建一个B的子类,你需要实现这个方法

      public class B1 extends B<Bar>{
      
        //You are required to implement this method as it is abstract.
        public Bar buildE(){
          ..
        }
      
        private void anyMethod(){
          //call B.foo() which will use B1.buildE() to build a Bar
          super.foo();
        }
      
      }
      

      恕我直言,第二个解决方案要干净得多。

      【讨论】:

      • 您能否详细说明您提出的第二个解决方案?
      【解决方案3】:

      可以在B中使用反射获取Class&lt;E&gt;,然后获取想要的构造函数并调用newInstance

      (Class<E>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]
      

      【讨论】:

      • -1 这假定this 是扩展B 并使用具体类型解析其类型参数的类的实例,例如class C extends B&lt;String&gt;.
      • @Paul Bellora 提问者问“在B的一个方法中,我想得到一个E的虚拟实例”,所以this当然是一个具体的类
      • 请重新阅读我的评论以了解它。用new B&lt;A&gt; 试试——它会在(ParameterizedType)this.getClass().getGenericSuperclass() 上失败。确保在使用之前了解模式。
      • 它会因new B&lt;String&gt; 而失败,但不会因new B&lt;E&gt; 而失败,其中E 扩展AA 是提问者创建的抽象类。我在生产中使用此代码,所以想提供一个替代建议。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 2018-01-02
      • 2010-11-08
      • 1970-01-01
      相关资源
      最近更新 更多