首页 > 解决方案 > Java:创建一个包含 N 个子类实例的向量

问题描述

我希望能够从继承到子类的静态方法中获取包含 N 个新实例的 List/ArrayList,这样我就不必在所有子类中重写这个相同的函数。

我想实现这个,这样我就可以构建一个包含一些 A 和 B 的向量。我尝试了几种方法,但没有一个对我有用:

public class Parent {

   public static List<Parent> getNInstances(int n) {
       List<Parent> out = new ArrayList<>();
       for (int i = 0; i < n; i++) {
          Parent newChildInstance = (Parent) MethodHandles
                                               .lookup()
                                               .lookupClass()
                                               .getConstructor()
                                               .newInstance()
          out.add(newChildInstance);
      }
   } 
}

我从这里得到了 MethodHandles 的东西,因为我觉得我需要让类能够调用.getConstructor().newInstance(),理论上应该可以解决我的问题。尽管如此,这不起作用,它给了我一个 NoSuchMethodException ,因为他无法从 给出的 Class 中找到构造函数 MethodHandles.lookup().lookupClass(),至少我认为这就是原因。

这是我希望该方法.getNInstances()起作用的方式。

public class Parent {

   public Parent(){  }

   public static List<Parent> getNInstances(int n) {
   List<Parent> out = new ArrayList<>();
   for (int i = 0; i < n; i++) {
      Parent newChildInstance = ...
      out.add(newChildInstance);
      }
   } 
}
public class A extends Parent {
   public A(){ }
}
public class B extends Parent {
   public B(){ }
}
public class Main {
   public static void main(String[] args) {
       List<Parent> total = new ArrayList<>();

       total.addAll(A.getNInstances(3));
       total.addAll(B.getNInstances(4));
   }
}

因此,这里的总应该像 [a, a, a, b, b, b, b] 其中 a 是 A 的实例, b 是 B 的实例,但现在它只是空的。

标签: javainheritancemethodsinstance

解决方案


这里根本不需要使用反射。为构造函数使用工厂和方法引用。

这样,您就可以在编译时确保您尝试使用的构造函数确实存在。

abstract class ParentFactory
{
    public List<Parent> getNInstances(int n)
    {
        final List<Parent> out = new ArrayList<>();
        for (int i = 0; i < n; i++)
        {
            out.add(constructor().get());
        }
        return out;
    }

    protected abstract Supplier<Parent> constructor();
}

class AFactory extends ParentFactory
{
    @Override
    protected Supplier<Parent> constructor() {
        return A::new;
    }
}

class BFactory extends ParentFactory
{
    @Override
    protected Supplier<Parent> constructor() {
        return B::new;
    }
}

示例用法:

List<Parent> total = new ArrayList<>();

total.addAll(new AFactory().getNInstances(3));
total.addAll(new BFactory().getNInstances(4));

推荐阅读