1

我为每个类使用一个 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>();
    }
}

我尝试了很多谷歌并使用 java 反射(Object.getClass()Constructor.newInstance()Class.newInstance())。然而我并没有成功。

4

3 回答 3

1

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

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());
于 2014-04-10T20:24:32.400 回答
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 );

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

于 2014-04-10T20:16:14.227 回答
0

这是一个可能的解决方案。为了防止像 Mike 在他的评论中建议的那样使用 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 中,您可以使用 Lambda 更优雅地做到这一点:

Ham[] ham1 = new Ham[13];
fillArray(ham1, idx -> new Ham());
fillArray(ham1, idx -> new Ham(getParameterForIndex(idx)));
于 2014-04-10T20:15:33.123 回答