1

I use an init method per classes.

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

Is it possible to define a kind of "universal" method to init any kind of object?

Like at least:

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

I tried to Google a lot and to play with java reflection also (Object.getClass(); Constructor.newInstance(); Class.newInstance() ). However I have not been successful.

4
  • Well usually you don't just want to call a parameterless constructor... Commented Apr 10, 2014 at 20:09
  • 1
    "I have not been successful" is not a good problem description. What did you try and where did it go wrong? Aside from that: is it really a problem? How often do you use a parameterless constructor of a self defined type? Commented Apr 10, 2014 at 20:11
  • Are you trying to follow Sagan's recipe for apple pie? I can't get the crust right either. Commented Apr 10, 2014 at 20:23
  • Thank you for your answers. I see your points and probably parameterless constructor not make so much sense. This thing just came into my mind when I was doing some experiments for better understanding. Because this all thing came from exercising I did a lot of overwritings and I could not find my previous achievements but I would try to reconstruct the things with reflection. Commented Apr 10, 2014 at 20:36

3 Answers 3

1

Using a Supplier to specify the way to create an instance:

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

Instead of

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

you could do

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

or in Java 8

Foo[] foos = fullArray(Foo.class, 42, () -> new Foo());
Sign up to request clarification or add additional context in comments.

1 Comment

When using Java 8, the Supplier interface is now part of the language. Which means a lambda can be used.
1

If I understand the question correctly I think you want this (note: handle or propagate the exceptions any way you wish to):

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

Then you can use it like this (very simple):

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

The class will need to have a default constructor.

1 Comment

Class.newIntance has a specification bug in that it silently converts checked exceptions to unchecked.
0

Here is a possible solution. To prevent using Class.newInstance() as Mike suggest in his comment, I changed the implementation. It would also support a constructor with possible parameters

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

Your call would look like this:

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

Or with custom constructor parameters:

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

With Java 8 you can do this even more elegantly using Lambdas:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.