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