是否有" UNIVERSAL"初始化对象数组的方法? (JAVA)

时间:2014-04-10 20:07:42

标签: java arrays methods constructor array-initialization

我每个类使用一个init方法。

Spam[] spam1 = new Spam[13];
Spam[] spam2 = new Spam[7];
Spam[] spam3 = new Spam[5];

initSpamArray(spam1);
initSpamArray(spam2);
initSpamArray(spam3);

void initSpamArray (Object[] a) {
    for (int i = 0, len = a.length; i < len; i++) {
        a[i] = new Spam();
    }
}


Ham[] ham1 = new Ham[13];
Ham[] ham2 = new ham[7];
Ham[] ham3 = new Ham[5];

initHamArray(ham1);
initHamArray(ham2);
initHamArray(ham3);

void initHamArray (Object[] a) {
    for (int i = 0, len = a.length; i < len; i++) {
        a[i] = new Ham();
    }
}

是否可以定义一种“通用”方法来初始化任何类型的对象?

至少像:

void initObjArray (Object[] a, <s.g. which suitable to transfer Class>) {
    for (int i = 0, len = a.length; i < len; i++) {
        a[i] = new <s.g. which suitable to transfer Class>();
    }
}

我尝试了很多Google并使用java反射( Object.getClass(); Constructor.newInstance(); Class.newInstance( ))。但是我没有成功。

3 个答案:

答案 0 :(得分:1)

如果我正确理解了这个问题,我认为你想要这个(注意:按照你希望的方式处理或传播例外):

public static <T> T[] newDefaultArray( Class<T> type, int N ) {
    T[] array = (T[])Array.newInstance(type, N);
    for ( int at = 0; at != N; ++at ) {
        try {
            array[at] = type.newInstance();
        }
        catch ( Exception e ) {
           throw new RuntimeException( e );
        }
    }

    return array;
}

然后你可以像这样使用它(非常简单):

   User[] users = newDefaultArray( User.class, 100 );

该类需要一个默认的构造函数。

答案 1 :(得分:1)

使用Supplier指定创建实例的方式:

public static <T> T[] fullArray(Class<T> componentType, int n,
                                Supplier<? extends T> constructor) {
  // This introduces no new type-unsafety.
  // Array.newInstance has to return Object since it can take a primitive
  // component type and !(new int[0] instanceof Object[]), but we know that
  // the result is a reference type since type parameters like T can only
  // bind to reference types.
  @SuppressWarnings("unchecked")
  T[] array = (T[]) Array.newInstance(componentType, n);
  for (int i = 0; i < n; ++i) {
    array[i] = constructor.get();
  }
  return array;
}

而不是

Foo[] foos = new Foo[42];
for (int i = 0; i < foos.length; ++i) {
  foos[i] = new Foo();
}

你可以做到

Foo[] foos = fullArray(
    Foo.class, 42,
    new Supplier<Foo>() { public Foo get() { return new Foo(); } });

或在Java 8中

Foo[] foos = fullArray(Foo.class, 42, () -> new Foo());

答案 2 :(得分:0)

这是一个可能的解决方案。 为了防止在他的评论中使用Class.newInstance(),我改变了实现。它还支持具有可能参数的构造函数

public <T> void fillArray(T[] a, ArrayFillFunction<? extends T> f)
{
    for (int i = 0, len = a.length; i < len; i++)
    {
        a[i] = f.fill(i);
    }
}

public interface ArrayFillFunction<T> {
    T fill(int idx);
}

您的电话将如下所示:

Ham[] ham1 = new Ham[13];
fillArray(ham1, new ArrayFillFunction<Ham>()
{
    public Ham fill(int idx)
    {
        return new Ham();
    }
});

或使用自定义构造函数参数:

Ham[] ham1 = new Ham[13];
fillArray(ham1, new ArrayFillFunction<Ham>()
{
    public Ham fill(int idx)
    {
        return new Ham(getParameterForIndex(idx));
    }
});

使用Java 8,您可以使用Lambdas更优雅地完成此任务:

Ham[] ham1 = new Ham[13];
fillArray(ham1, idx -> new Ham());
fillArray(ham1, idx -> new Ham(getParameterForIndex(idx)));