Java的:创建子类的N个实例的矢量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的:创建子类的N个实例的矢量相关的知识,希望对你有一定的参考价值。

我希望能够从继承到子类的静态方法得到N个新的实例列表/ 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);
      }
   } 
}

我得从here的MethodHandles的事情,因为我觉得我需要的类能够调用.getConstructor().newInstance()应,在理论上,解决我的问题。尽管如此,这并不工作,它给了我一个NoSuchMethodException,因为他无法找到由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的一个实例,但现在,它只是空的。

答案

有没有必要在这里使用反射。使用工厂和构造方法的参考。

这样,您有编译时保证,你要实际使用的构造存在。

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));
另一答案

我不设法重现你的错误。但需要注意的一些要点:

1)在这里,因为lookupClass()返回调用该方法的类,这是永远Parent.getNInstances()你永远不会查找一个类的子类:

Parent newChildInstance = (Parent) MethodHandles
        .lookup()
        .lookupClass()
        .getConstructor()
        .newInstance();

使它成为一个实例方法会产生相同的结果。

2)通用类应该是足以解决你的问题,并使其实例方法。

public class Parent<T extends Parent> {

    public List<Parent> getNInstances(int n) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        List<Parent> out = new ArrayList<>();
        for (int i = 0; i < n; i++) {

            Class<T> clazz = (Class<T>) ((ParameterizedType) getClass()
                    .getGenericSuperclass()).getActualTypeArguments()[0];
            Parent newChildInstance =
                    clazz.getConstructor().newInstance();

            out.add(newChildInstance);
        }
        return out;
    }

}

和子类:

public class A extends Parent<A> {
    //...
}

public class B extends Parent<B> {
    //...
}

样品测试:

List<Parent> total = new ArrayList<>();    
total.addAll(new A().getNInstances(3));
total.addAll(new B().getNInstances(4));

System.out.println(total);

输出:

[A @ 506e6d5e,A @ 96532d6,A @ 3796751b,B @ 67b64c45,B @ 4411d970,B @ 6442b0a6,B @ 60f82f98]

以上是关于Java的:创建子类的N个实例的矢量的主要内容,如果未能解决你的问题,请参考以下文章

java 代码片段

java中,当实例化子类时会递归调用父类中的构造方法。这个说法对么?为啥

片段 null 必须是公共静态类才能从实例状态正确重新创建

如何防止创建相同片段的 2 个实例?

片段实例中带有 Otto 事件总线的 IllegalArgumentException

Java对象初始化顺序