有没有"UNIVERSAL"方法来初始化对象数组?(爪哇)



我为每个类使用一个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()构造函数.newInstance()类.newInstance())。然而,我并没有成功。

使用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());

如果我正确理解这个问题,我认为你想要这个(注意:以任何方式处理或传播异常):

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 );

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

这里有一个可能的解决方案。为了防止像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));
    }
});

使用Java8,您可以使用Lambdas:更优雅地实现这一点

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

相关内容

  • 没有找到相关文章