Question

In. NET, I can do something like this:

public static T[] CreateAndFillArray<T>(int size) where T : new()
{
   T[] array = new T[size];
   for (int i = size - 1; i >= 0; i--)
       array[i] = new T();
   return array;
}

We must to specify "where T : new()" clause.

How to do it in Java?

Was it helpful?

Solution

In Java, you cannot instantiate a generic array. (e.g. new T[size] can not work) This is because at runtime the types of generics are lost ("erasure") and cannot be recovered.

Is there a reason you can not use, for example, new ArrayList<T>()?

OTHER TIPS

You will not be able to create an array of generic "T" type in java unless you pass in T as parameter.

public static <T> T[] createAndFillArray(Class<T> cls, int size) {
  T[] result = (T[]) Array.newInstance(cls, size);
  for (int i=0; i<size; i++) {
    result[i] = cls.newInstance();
  }
  return result;
}

Java does not have an equivalent construct. There is no compile time safety on a class containing a constructor.

You can do it at runtime, but you have to either pass a non-null T or a Class as a parameter. The actual type parameter used is not retained at runtime.

public static <T> T[] createAndFillArray(T sampleObject, int size) throws Exception {
        Class<T> klass = sampleObject.getClass();
        T[] arr = (T[]) Array.newInstance(klass, size);
        for (int i = 0; i < size; i++) {
            arr[i] = klass.newInstance();
        }
        return arr;
}

The above will work but throw an exception if there is no public no argument constructor. You cannot get the compiler to enforce that there is one.

Edit: ChssPly76 beat me to it, so I modified the above code to give an example where you pass in an actual object sample, just to show how it is done. Normally in such a case you would pass in the class because the sampleObject doesn't end up in the array.

You can use this idea to fix the lack of compile time checking in the other answers:

import java.lang.reflect.Array;

public class Main
{
    public static void main(String[] args)
    {
        final String[] array;

        array = createAndFillArray(String.class, 10, new StringCreator());

        for(final String s : array)
        {
            System.out.println(s);
        }
    }

    public static <T> T[] createAndFillArray(final Class<T>   clazz,
                                             final int        size,
                                             final Creator<T> creator)
    {
        T[] result = (T[]) Array.newInstance(clazz, size);

        for (int i=0; i<size; i++)
        {
            result[i] = creator.newInstance();
        }

        return result;
    }
}

interface Creator<T>
{
    T newInstance();
}

class StringCreator
    implements Creator<String>
{
    public String newInstance()
    {
        // not the best example since String is immutable but you get the idea
        // you could even have newInstance take an int which is the index of the 
        // item being created if that could be useful (which it might).
        return ("hello");
    }
}

This is actually more flexible than the C# way you describe since you can control the constructor if you want rather than simply calling the no-arg one.

You cannot do this in Java, because Java does not support structural type checks.

Scala does, but it's a lot slower than implementing an appropriate interface (since it uses reflection internally to make the function calls). Scala doesn't let you set constraints on the form of the object's constructor. The JVM uses type erasure, so the generic code doesn't actually know what type it's operating on, so it can't construct new objects of that type anyway.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top