By tatsuhirosatou


2009-02-09 17:30:44 8 Comments

Due to the implementation of Java generics, you can't have code like this:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

How can I implement this while maintaining type safety?

I saw a solution on the Java forums that goes like this:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

But I really don't get what's going on.

29 comments

@saka1029 2017-07-11 21:53:55

You do not need to pass the Class argument to the constructor. Try this.

public class GenSet<T> {
    private final T[] array;
    @SuppressWarnings("unchecked")
    public GenSet(int capacity, T... dummy) {
        if (dummy.length > 0)
            throw new IllegalArgumentException(
              "Do not provide values for dummy argument.");
        Class<?> c = dummy.getClass().getComponentType();
        array = (T[])Array.newInstance(c, capacity);
    }
    @Override
    public String toString() {
        return "GenSet of " + array.getClass().getComponentType().getName()
            + "[" + array.length + "]";
    }
}

and

GenSet<Integer> intSet = new GenSet<>(3);
System.out.println(intSet);
System.out.println(new GenSet<String>(2));

result:

GenSet of java.lang.Integer[3]
GenSet of java.lang.String[2]

@dimo414 2010-05-27 20:00:45

You can do this:

E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH];

This is one of the suggested ways of implementing a generic collection in Effective Java; Item 26. No type errors, no need to cast the array repeatedly. However this triggers a warning because it is potentially dangerous, and should be used with caution. As detailed in the comments, this Object[] is now masquerading as our E[] type, and can cause unexpected errors or ClassCastExceptions if used unsafely.

As a rule of thumb, this behavior is safe as long as the cast array is used internally (e.g. to back a data structure), and not returned or exposed to client code. Should you need to return an array of a generic type to other code, the reflection Array class you mention is the right way to go.


Worth mentioning that wherever possible, you'll have a much happier time working with Lists rather than arrays if you're using generics. Certainly sometimes you don't have a choice, but using the collections framework is far more robust.

@Lawrence Dol 2010-10-11 16:09:20

This will not work if the array is treated as a typed array of any kind, such as String[] s=b; in the above test() method. That's because the array of E isn't really, it's Object[]. This matters if you want, e.g. a List<String>[] - you can't use an Object[] for that, you must have a List[] specifically. Which is why you need to use the reflected Class<?> array creation.

@misiu_mp 2011-08-10 19:57:46

@SoftwareMonkey I tried this with List<String> as E. Running it with as t.genericArrayTest(Arrays.asList("Hello World")); Works great.

@Lawrence Dol 2011-08-10 20:04:03

The corner-case/problem is if you want to do, for example, public E[] toArray() { return (E[])internalArray.clone(); } when internalArray is typed as E[], and is therefore actually an Object[]. This fails at runtime with a type-cast exception because an Object[] cannot be assigned to an array of whatever type E happens to be.

@newacct 2011-09-23 22:07:46

Basically, this approach will work as long as you do not return the array or pass it or store it in some place outside of the class that requires an array of a certain type. As long as you're inside the class you're fine because E is erased. It's "dangerous" because if you try to return it or something, you get no warning that it's unsafe. But if you're careful then it works.

@Aaron McDaid 2012-01-21 19:53:30

It is quite safe. In E[] b = (E[])new Object[1]; you can clearly see that the only reference to the created array is b and that the type of b is E[]. Therefore there is no danger of you accidentally accessing the same array through a different variable of a different type. If instead, you had Object[] a = new Object[1]; E[]b = (E[])a; then you would need to be paranoid about how you use a.

@Quantum7 2012-03-24 00:42:33

At least in Java 1.6, this generates a warning: "Unchecked cast from Object[] to T[]"

@dimo414 2012-03-25 05:44:20

Very odd, I would have been using 1.6 when I made this post, but I'm also seeing a warning now too.

@Ryan Shillington 2012-05-16 20:19:24

Genius! This works in GWT too, where reflection won't work. Thank you! BTW, add @SuppressWarnings("unchecked") to get rid of the warning.

@newacct 2012-05-21 18:26:33

Why is this "no longer correct"?

@Blackzafiro 2015-03-18 17:12:14

It is not correct because b is an array of Objects. You should just write Object[] b = new Object[1], anything else is cheating yourself and the compiler (perhaps getting it to let you know, if it was your intention to only store Strings inside, when you are not being consistent). You can store a String in an array of Objects because String inherits from Object, but you certainly have not created an array of Strings.

@dimo414 2015-03-18 19:56:12

@Blackzafiro like I said, "this Object[] is now masquerading as our E[] type" - this method should only be used when we can trust the array won't be passed around or otherwise misused. For private/internal code, it's reasonably safe.

@user4229245 2015-04-03 20:28:52

@dimo414, safe but only for "private/internal code"? To be clear for the not "private/internal code", I'm sorry guys, but this smacks of being a fairly crummy idiom. (E[])(new Object[1]) is just not something a tired engineer at 3am is going to immediately see the pitfalls for and smacks of something that is of the form Disaster Waiting to Happen®. I wouldn't use it for something I was writing solely for myself.

@dimo414 2015-04-03 23:06:22

@tgm1024 it's fine by me if you don't want to use it. You shouldn't be mixing generics and arrays in the first place, so I don't think the problem is really with this solution. It's about as safe as using raw types, which is certainly not recommended, but for code that doesn't expose the array, is generally not actively harmful. As I've said, this isn't ideal, but it is easy. Sometimes, that tradeoff is ok.

@Singagirl 2016-08-22 06:47:42

It brings cast exception if for example return such array from a method where a caller expects certain type.

@dimo414 2016-08-22 13:31:51

@dmitriyr yes, like I said in the answer this isn't safe for general use; it's best used for internal data structures where you control access to the array. If you need to return a dynamically-typed array to callers (why? use List instead) you need to use reflection.

@Eugene 2018-11-10 19:18:15

@newacct while you are correct that if you don't expose the generic array you should be fine, it will only work with unbouded types. For example this will still fail static <T extends Foo> void testMe(T elem) { T[] array = (T[]) new Object[]{elem}; } because in this case the erased type will be Foo and not Object

@newacct 2018-11-11 02:12:20

@Eugene: you would use the erasure of T as the component type when creating the array. So if the erasure of T is Foo, then you would do array = (T[])new Foo[length];

@Brad Mace 2018-11-29 18:49:18

@Irfan Ul Haq 2018-04-19 13:45:59

Generic array creation is disallowed in java but you can do it like

class Stack<T> {
private final T[] array;
public Stack(int capacity) {
    array = (T[]) new Object[capacity];
 }
}

@Rodrigo Asensio 2017-09-15 10:19:41

Passing a list of values...

public <T> T[] array(T... values) {
    return values;
}

@Radiodef 2014-03-05 14:14:02

In Java 8, we can do a kind of generic array creation using a lambda or method reference. This is similar to the reflective approach (which passes a Class), but here we aren't using reflection.

@FunctionalInterface
interface ArraySupplier<E> {
    E[] get(int length);
}

class GenericSet<E> {
    private final ArraySupplier<E> supplier;
    private E[] array;

    GenericSet(ArraySupplier<E> supplier) {
        this.supplier = supplier;
        this.array    = supplier.get(10);
    }

    public static void main(String[] args) {
        GenericSet<String> ofString =
            new GenericSet<>(String[]::new);
        GenericSet<Double> ofDouble =
            new GenericSet<>(Double[]::new);
    }
}

For example, this is used by <A> A[] Stream.toArray(IntFunction<A[]>).

This could also be done pre-Java 8 using anonymous classes but it's more cumbersome.

@Lii 2015-12-27 23:49:23

You don't really need a special interface like ArraySupplier for this, you can declare the constructor as GenSet(Supplier<E[]> supplier) { ... and call it with the same line as you have.

@Radiodef 2015-12-28 16:16:27

@Lii To be the same as my example, it would be IntFunction<E[]>, but yes that's true.

@Crab Nebula 2017-06-28 19:59:53

I actually found a pretty unique solution to bypass the inability to initiate a generic array. What you have to do is create a class that takes in the generic variable T like so:

class GenericInvoker <T> {
    T variable;
    public GenericInvoker(T variable){
        this.variable = variable;
    }
}

and then in your array class just have it start like so:

GenericInvoker<T>[] array;
public MyArray(){
    array = new GenericInvoker[];
}

starting a new Generic Invoker[] will cause an issue with unchecked but there shouldn't actually be any issues.

To get from the array you should call the array[i].variable like so:

public T get(int index){
    return array[index].variable;
}

The rest, such as resizing the array can be done with Arrays.copyOf() like so:

public void resize(int newSize){
    array = Arrays.copyOf(array, newSize);
}

And the add function can be added like so:

public boolean add(T element){
    // the variable size below is equal to how many times the add function has been called 
    // and is used to keep track of where to put the next variable in the array
    arrays[size] = new GenericInvoker(element);
    size++;
}

@Sotirios Delimanolis 2017-06-29 15:14:46

The question was about creating an array of the type of the generic type parameter T, not an array of some parameterized type.

@Crab Nebula 2017-06-29 23:50:43

It completes the same task though and doesn't require you pushing in a class making your custom collection easier to use.

@Sotirios Delimanolis 2017-06-30 00:16:17

What task? It's literally a different task: an array of a paramaterized type vs an array of a generic type parameter.

@Crab Nebula 2017-06-30 23:53:48

It allows you to create an array from a generic type? The original problem was initializing an array using a generic type which using my method allows you to do without having to have the user push in a class or give an unchecked error such as trying to cast an Object to a String. Like chill, I'm not the best at what I do, and I haven't gone to school for programming but I think I still deserve a little input rather than being told off by some other kid on the internet.

@Stephen C 2017-07-11 23:00:28

I agree with Sotiros. There are two ways to think of the answer. Either it is an answer to a different question, or it is an attempt to generalize the question. Both are wrong / not helpful. People who are looking for guidance on how to implement a "generic array" class would / stop reading when they read the question title. And when they find an Q with 30 answers, they are highly unlikely to scroll to the end and read a zero vote answer from a SO newcomer.

@Stephen C 2017-07-11 23:01:45

Finally, if they found your A "organically" and it was relevant, then they were lucky. You have "filed" it in the wrong place.

@Nik-Lz 2016-11-09 20:43:28

I have found a quick and easy way that works for me. Note that i have only used this on Java JDK 8. I don't know if it will work with previous versions.

Although we cannot instantiate a generic array of a specific type parameter, we can pass an already created array to a generic class constructor.

class GenArray <T> {
    private T theArray[]; // reference array

    // ...

    GenArray(T[] arr) {
        theArray = arr;
    }

    // Do whatever with the array...
}

Now in main we can create the array like so:

class GenArrayDemo {
    public static void main(String[] args) {
        int size = 10; // array size
        // Here we can instantiate the array of the type we want, say Character (no primitive types allowed in generics)
        Character[] ar = new Character[size];

        GenArray<Character> = new Character<>(ar); // create the generic Array

        // ...

    }
}

For more flexibility with your arrays you can use a linked list eg. the ArrayList and other methods found in the Java.util.ArrayList class.

@developer747 2016-10-19 01:04:54

I found a sort of a work around to this problem.

The line below throws generic array creation error

List<Person>[] personLists=new ArrayList<Person>()[10];

However if I encapsulate List<Person> in a separate class, it works.

import java.util.ArrayList;
import java.util.List;


public class PersonList {

    List<Person> people;

    public PersonList()
    {
        people=new ArrayList<Person>();
    }
}

You can expose people in the class PersonList thru a getter. The line below will give you an array, that has a List<Person> in every element. In other words array of List<Person>.

PersonList[] personLists=new PersonList[10];

I needed something like this in some code I was working on and this is what I did to get it to work. So far no problems.

@Jeff Olson 2009-02-09 18:50:42

This is covered in Chapter 5 (Generics) of Effective Java, 2nd Edition, item 25...Prefer lists to arrays

Your code will work, although it will generate an unchecked warning (which you could suppress with the following annotation:

@SuppressWarnings({"unchecked"})

However, it would probably be better to use a List instead of an Array.

There's an interesting discussion of this bug/feature on the OpenJDK project site.

@Benjamin M 2016-02-21 01:28:56

What about this solution?

@SafeVarargs
public static <T> T[] toGenericArray(T ... elems) {
    return elems;
}

It works and looks too simple to be true. Is there any drawback?

@orlade 2016-08-29 01:41:42

Neat, but only works if you call it 'manually', i.e. pass the elements individually. If you can't create a new instance of T[], then you can't programatically build up a T[] elems to pass into the function. And if you could, you wouldn't need the function.

@gdejohn 2010-11-19 03:30:15

Here's how to use generics to get an array of precisely the type you’re looking for while preserving type safety (as opposed to the other answers, which will either give you back an Object array or result in warnings at compile time):

import java.lang.reflect.Array;  

public class GenSet<E> {  
    private E[] a;  

    public GenSet(Class<E[]> clazz, int length) {  
        a = clazz.cast(Array.newInstance(clazz.getComponentType(), length));  
    }  

    public static void main(String[] args) {  
        GenSet<String> foo = new GenSet<String>(String[].class, 1);  
        String[] bar = foo.a;  
        foo.a[0] = "xyzzy";  
        String baz = foo.a[0];  
    }  
}

That compiles without warnings, and as you can see in main, for whatever type you declare an instance of GenSet as, you can assign a to an array of that type, and you can assign an element from a to a variable of that type, meaning that the array and the values in the array are of the correct type.

It works by using class literals as runtime type tokens, as discussed in the Java Tutorials. Class literals are treated by the compiler as instances of java.lang.Class. To use one, simply follow the name of a class with .class. So, String.class acts as a Class object representing the class String. This also works for interfaces, enums, any-dimensional arrays (e.g. String[].class), primitives (e.g. int.class), and the keyword void (i.e. void.class).

Class itself is generic (declared as Class<T>, where T stands for the type that the Class object is representing), meaning that the type of String.class is Class<String>.

So, whenever you call the constructor for GenSet, you pass in a class literal for the first argument representing an array of the GenSet instance's declared type (e.g. String[].class for GenSet<String>). Note that you won't be able to get an array of primitives, since primitives can't be used for type variables.

Inside the constructor, calling the method cast returns the passed Object argument cast to the class represented by the Class object on which the method was called. Calling the static method newInstance in java.lang.reflect.Array returns as an Object an array of the type represented by the Class object passed as the first argument and of the length specified by the int passed as the second argument. Calling the method getComponentType returns a Class object representing the component type of the array represented by the Class object on which the method was called (e.g. String.class for String[].class, null if the Class object doesn't represent an array).

That last sentence isn't entirely accurate. Calling String[].class.getComponentType() returns a Class object representing the class String, but its type is Class<?>, not Class<String>, which is why you can't do something like the following.

String foo = String[].class.getComponentType().cast("bar"); // won't compile

Same goes for every method in Class that returns a Class object.

Regarding Joachim Sauer's comment on this answer (I don't have enough reputation to comment on it myself), the example using the cast to T[] will result in a warning because the compiler can't guarantee type safety in that case.


Edit regarding Ingo's comments:

public static <T> T[] newArray(Class<T[]> type, int size) {
   return type.cast(Array.newInstance(type.getComponentType(), size));
}

@Ingo 2011-03-21 10:11:10

This is useless, it is only a complicated way to write new String[...]. But what is really needed is something like public static <T> T[] newArray(int size) { ... }, and this simply does not exist in java noir can it be simulated with reflection - the reason is that information about how a generic type is instantiated is not available at runtime.

@gdejohn 2011-03-23 12:34:03

@Ingo What are you talking about? My code can be used to create an array of any type.

@Ingo 2011-03-23 12:48:24

@Charlatan: Sure, but so can new []. The question is: who knows the type and when. Therefore, if all you have is a generic type, you can't.

@gdejohn 2011-03-23 12:54:29

@Ingo That's static. This is dynamic. I'm not sure what you don't understand.

@Ingo 2011-03-23 12:58:46

I don't doubt that. The point is, you don't get a Class object at runtime for generic type X.

@gdejohn 2011-03-23 13:04:10

@Ingo See the edit to my answer. Is that not what you're talking about? Because that compiles without warning and returns an array of the desired type.

@Ingo 2011-03-23 13:31:04

Almost. I admit that this is more than what can be achieved with new[]. In practice, this will almost always do the job. However, it is still not possible, for instance, to write a container class parameterized with E that has a method E[] toArray() and that indeed returns a true E[] array. Your code could be applied only when there is at least one E-object in the collection. So, a general solution is impossible.

@gdejohn 2011-03-23 13:45:53

@Ingo If you wanted that functionality, and you really wanted to avoid needing to suppress any warnings, then you could have an instance field of type Class and have the constructors take a corresponding argument to initialize it with. This could be done in a type-safe manner.

@misiu_mp 2011-08-10 22:29:29

@Charlatan How to get a Class object for type ArrayList<String>, in a type- safe manner? getClass() will return just ArrayList - no parameter. Getting ArrayList<String>[] is difficult too. Apparently one 'Cannot create a generic array of ArrayList<String>', but array of ArrayList is fine.

@gdejohn 2011-08-14 04:43:18

@misiu_mp Can't do that.

@misiu_mp 2011-10-04 10:10:49

@Charlatan Ah, so 'have an instance field of type Class and have the constructors take a corresponding argument to initialize it with' cannot be done in a type safe manner after all?

@gdejohn 2011-10-04 22:50:28

@misiu_mp Yes, it can. That will compile without warnings and give you what you want. It's obviously just not an option for the preexisting ArrayList implementation.

@misiu_mp 2011-10-11 12:59:36

@Charlatan Try to use ArrayList<String> as the generic argument in your example. GenSet<ArrayList<String>> foo = new GenSet< ArrayList<String> >( ArrayList<String>[].class, 1); I get a lot of errors in the ArrayList<String>[].class contraption.

@gdejohn 2011-10-13 15:15:16

@misiu_mp You can't parameterize class literals, due to type erasure.

@plugwash 2015-10-17 05:49:51

No one else has answered the question of what is going on in the example you posted.

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

As others have said generics are "erased" during compilation. So at runtime an instance of a generic doesn't know what its component type is. The reason for this is historical, Sun wanted to add generics without breaking the existing interface (both source and binary).

Arrays on the other hand do know their component type at runtime.

This example works around the problem by having the code that calls the constructor (which does know the type) pass a parameter telling the class the required type.

So the application would construct the class with something like

Stack<foo> = new Stack<foo>(foo.class,50)

and the constructor now knows (at runtime) what the component type is and can use that information to construct the array through the reflection API.

Array.newInstance(clazz, capacity);

Finally we have a type cast because the compiler has no way of knowing that the array returned by Array#newInstance() is the correct type (even though we know).

This style is a bit ugly but it can sometimes be the least bad solution to creating generic types that do need to know their component type at runtime for whatever reason (creating arrays, or creating instances of their component type, etc.).

@Pedram Esmaeeli 2015-06-12 09:40:46

Actually an easier way to do so, is to create an array of objects and cast it to your desired type like the following example:

T[] array = (T[])new Object[SIZE];

where SIZE is a constant and T is a type identifier

@Zubair Ibrhaim 2015-06-03 05:52:51

private E a[];
private int size;

public GenSet(int elem)
{
    size = elem;
    a = (E[]) new E[size];
}

@mjuarez 2015-06-03 06:11:29

You should always add an explanation to your code, and explain why it solves the original posted question.

@Varkhan 2009-02-09 22:19:31

I have to ask a question in return: is your GenSet "checked" or "unchecked"? What does that mean?

  • Checked: strong typing. GenSet knows explicitly what type of objects it contains (i.e. its constructor was explicitly called with a Class<E> argument, and methods will throw an exception when they are passed arguments that are not of type E. See Collections.checkedCollection.

    -> in that case, you should write:

    public class GenSet<E> {
    
        private E[] a;
    
        public GenSet(Class<E> c, int s) {
            // Use Array native method to create array
            // of a type only known at run time
            @SuppressWarnings("unchecked")
            final E[] a = (E[]) Array.newInstance(c, s);
            this.a = a;
        }
    
        E get(int i) {
            return a[i];
        }
    }
    
  • Unchecked: weak typing. No type checking is actually done on any of the objects passed as argument.

    -> in that case, you should write

    public class GenSet<E> {
    
        private Object[] a;
    
        public GenSet(int s) {
            a = new Object[s];
        }
    
        E get(int i) {
            @SuppressWarnings("unchecked")
            final E e = (E) a[i];
            return e;
        }
    }
    

    Note that the component type of the array should be the erasure of the type parameter:

    public class GenSet<E extends Foo> { // E has an upper bound of Foo
    
        private Foo[] a; // E erases to Foo, so use Foo[]
    
        public GenSet(int s) {
            a = new Foo[s];
        }
    
        ...
    }
    

All of this results from a known, and deliberate, weakness of generics in Java: it was implemented using erasure, so "generic" classes don't know what type argument they were created with at run time, and therefore can not provide type-safety unless some explicit mechanism (type-checking) is implemented.

@user1111929 2012-09-08 03:52:51

What would performance-wise be the best option? I need to get elements from this array quite often (within a loop). So a collection is probably slower, but which of these two is fastest?

@Mordechai 2013-04-08 05:59:03

And if the generic type is bounded, the backing array should be of the bounding type.

@kennytm 2013-09-26 12:17:32

@AaronDigulla Just to clarify that's not assignment, but initialization of a local variable. You can't annotate an expression/statement.

@JourneyMan 2014-08-28 17:53:26

@Varkhan Is there a way to resize these arrays from within the class implementation. For example if I want to resize after overflow like ArrayList. I looked up the Implementation of ArrayList they have Object[] EMPTY_ELEMENTDATA = {} for storage. Can I use this mechanism to resize without knowing the type using generics?

@Daniel Kvist 2015-03-13 14:44:27

For those who want to make a method with a generic type (which was what I was looking for), use this: public void <T> T[] newArray(Class<T> type, int length) { ... }

@gozzilli 2015-06-08 19:08:12

Does this mean that every time I instantiate GenSet of some type, say for example new GenSet<Float> I have to pass the Type.class (that is new GenSet<Float>(Float.class, 10)? Is there no way to write it as new GenSet<Float>(10) and still maintain the strong typing?

@Nyerguds 2017-11-06 08:44:01

@gozzilli Sadly not, because Java generics are basically, well, fake. You can't do anything without also having the class object.

@irreputable 2011-11-08 15:28:17

This is the only answer that is type safe

E[] a;

a = newArray(size);

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}

@seh 2012-10-04 19:53:30

I had to look it up, but yes, the second "length" argument to Arrays#copyOf() is independent of the length of the array supplied as the first argument. That's clever, though it does pay the cost of calls to Math#min() and System#arrayCopy(), neither of which are strictly necessary to get this job done. docs.oracle.com/javase/7/docs/api/java/util/…

@Radiodef 2015-04-06 04:13:12

This does not work if E is a type variable. The varargs creates an array of erasure of E when E is a type variable, making it not much different from (E[])new Object[n]. Please see http://ideone.com/T8xF91. It is by no means more type safe than any other answer.

@ZhongYu 2015-05-18 18:35:57

@Radiodef - the solution is provably type-safe at compile time. note that erasure is not exactly part of the language spec; the spec is written carefully so that we could have full reification in future - and then this solution would work perfectly at runtime too, unlike other solutions.

@ZhongYu 2015-05-18 18:38:20

@Radiodef - It's debatable whether banning generic array creation is a good idea. regardless, the language does leave a backdoor - vararg requires generic array creation. It is as good as if the language have permitted new E[]. The problem you showed in your example is a general erasure problem, not unique to this question and this answer.

@ZhongYu 2015-05-18 18:53:22

@Radiodef - type safety is a compile time concept. it's well-known that a type-safe Java program can fail at runtime, even before generics, e.g. array upcasting. you may have a different concept of 'type-safe', so it's merely a difference in definition. but OP is not wrong by calling it type-safe.

@ZhongYu 2015-05-18 19:03:41

@Radiodef - It is more of an academic distinction. (E[])new Object[n] is not type safe; actually it is obviously wrong from the language point of a view. It happens to work today, because of erasure. It will fail under full reification. But - who cares? Well, a few, who tries to be type-safe as much as possible, just for the sake of being a purist.

@ZhongYu 2015-05-18 19:19:28

@Radiodef - There are some differences. The correctness of this solution is checked by the compiler; it does not rely on human reasoning of forced cast. The difference is not significant for this particular problem. Some people just like to be a little fancy, that's all. If anyone is misled by OP's wording, it's clarified by your comments and mine.

@uraj 2015-08-17 18:04:43

What if E itself is a parameterized type, say List<String>?

@Eugene 2018-11-10 19:25:28

@irreputable I like this, but I don't think you need the length, you could just write it as return Arrays.copyOf(Objects.requireNonNull(array), array.length);

@samir benzenine 2014-09-15 17:23:32

You could use a cast:

public class GenSet<Item> {
    private Item[] a;

    public GenSet(int s) {
        a = (Item[]) new Object[s];
    }
}

@Radiodef 2015-04-06 04:00:53

If you are going to suggest this, you really need to explain its limitations. Never expose a to outside the class!

@Cambot 2014-07-09 13:36:35

I'm wondering if this code would create an effective generic array?

public T [] createArray(int desiredSize){
    ArrayList<T> builder = new ArrayList<T>();
    for(int x=0;x<desiredSize;x++){
        builder.add(null);
    }
    return builder.toArray(zeroArray());
}

//zeroArray should, in theory, create a zero-sized array of T
//when it is not given any parameters.

private T [] zeroArray(T... i){
    return i;
}

Edit: Perhaps an alternate way of creating such an array, if the size you required was known and small, would be to simply feed the required number of "null"s into the zeroArray command?

Though obviously this isn't as versatile as using the createArray code.

@Radiodef 2015-04-06 04:03:56

No, this does not work. The varargs creates erasure of T when T is a type variable, i.e. zeroArray returns an Object[]. See http://ideone.com/T8xF91.

@Jason C 2013-08-15 13:47:19

To extend to more dimensions, just add []'s and dimension parameters to newInstance() (T is a type parameter, cls is a Class<T>, d1 through d5 are integers):

T[] array = (T[])Array.newInstance(cls, d1);
T[][] array = (T[][])Array.newInstance(cls, d1, d2);
T[][][] array = (T[][][])Array.newInstance(cls, d1, d2, d3);
T[][][][] array = (T[][][][])Array.newInstance(cls, d1, d2, d3, d4);
T[][][][][] array = (T[][][][][])Array.newInstance(cls, d1, d2, d3, d4, d5);

See Array.newInstance() for details.

@Paul Bellora 2013-08-15 13:52:53

+1 There have been questions about multi-dimensional array creation that get closed as dupes of this post - but no answers had specifically addressed that.

@JordanC 2014-11-11 19:48:42

Could this be an answer here?: stackoverflow.com/q/5670972

@Jason C 2014-11-12 05:19:23

@JordanC Maybe; although it is the same in spirit as stackoverflow.com/a/5671304/616460; I will think about best way to handle tomorrow. I am sleepy.

@vnportnoy 2013-09-14 21:26:33

The forced cast suggested by other people did not work for me, throwing an exception of illegal casting.

However, this implicit cast worked fine:

Item<K>[] array = new Item[SIZE];

where Item is a class I defined containing the member:

private K value;

This way you get an array of type K (if the item only has the value) or any generic type you want defined in the class Item.

@Mohsen Afshin 2013-08-21 16:11:35

Maybe unrelated to this question but while I was getting the "generic array creation" error for using

Tuple<Long,String>[] tupleArray = new Tuple<Long,String>[10];

I find out the following works (and worked for me) with @SuppressWarnings({"unchecked"}):

 Tuple<Long, String>[] tupleArray = new Tuple[10];

@Paul Bellora 2013-08-21 16:23:07

Yeah, this is not quite related, but rooted in the same issues (erasure, array covariance). Here's an example of a post about creating arrays of parameterized types: stackoverflow.com/questions/9542076/…

@MatheusJardimB 2013-08-08 23:32:27

Look also to this code:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

It converts a list of any kind of object to an array of the same type.

@Kevin Cox 2014-02-07 14:05:36

This of course fails if the array is empty.

@MatheusJardimB 2014-02-07 14:40:12

by array you mean obj? if so, I didn't get your point

@Kevin Cox 2014-02-07 14:49:38

Yes, you return null, which isn't the expected empty array. It is the best you can do, but not ideal.

@MatheusJardimB 2014-02-07 14:50:55

Thanks, got it :)

@Radiodef 2015-04-06 04:36:23

This can also fail if the List has more than one type of object in it e.g. toArray(Arrays.asList("abc", new Object())) will throw ArrayStoreException.

@bbarker 2015-08-10 01:04:57

I used a stripped down version of this; first thing I was able to use that worked, though admittedly I didn't try some of the more involved solutions. To avoid a for loop and others I used Arrays.fill(res, obj); since I wanted the same value for each index.

@puneeth 2011-06-14 19:26:00

Hi although the thread is dead, I would like to draw your attention to this:

Generics is used for type checking during compile time:

  • Therefore the purpose is to check that what comes in is what you need.
  • What you return is what the consumer needs.
  • Check this:

enter image description here

Do don't worry about typecasting warnings when you are writing generic class. Worry when you are using it.

@Bobster 2012-08-31 10:39:28

I made this code snippet to reflectively instantiate a class which is passed for a simple automated test utility.

Object attributeValue = null;
try {
    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }
    else if(!clazz.isInterface()){
        attributeValue = BeanUtils.instantiateClass(clazz);
    }
} catch (Exception e) {
    logger.debug("Cannot instanciate \"{}\"", new Object[]{clazz});
}

Note this segment:

    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }

for array initiating where Array.newInstance(class of array, size of array). Class can be both primitive (int.class) and object (Integer.class).

BeanUtils is part of Spring.

@StarMonkey 2012-04-05 00:10:45

An easy, albeit messy workaround to this would be to nest a second "holder" class inside of your main class, and use it to hold your data.

public class Whatever<Thing>{
    private class Holder<OtherThing>{
        OtherThing thing;
    }
    public Holder<Thing>[] arrayOfHolders = new Holder<Thing>[10]
}

@Radiodef 2014-03-10 19:43:54

This doesn't actually work. new Holder<Thing>[10] is a generic array creation.

@David Bernard 2011-02-13 20:37:34

try this.

private int m = 0;
private int n = 0;
private Element<T>[][] elements = null;

public MatrixData(int m, int n)
{
    this.m = m;
    this.n = n;

    this.elements = new Element[m][n];
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            this.elements[i][j] = new Element<T>();
        }
    }
}

@user8389458 2018-02-21 00:15:00

I can't get your code running, where does your Element class comes from?

@Bill Michell 2009-02-11 10:07:35

Java generics work by checking types at compile time and inserting appropriate casts, but erasing the types in the compiled files. This makes generic libraries usable by code which doesn't understand generics (which was a deliberate design decision) but which means you can't normally find out what the type is at run time.

The public Stack(Class<T> clazz,int capacity) constructor requires you to pass a Class object at run time, which means class information is available at runtime to code that needs it. And the Class<T> form means that the compiler will check that the Class object you pass is precisely the Class object for type T. Not a subclass of T, not a superclass of T, but precisely T.

This then means that you can create an array object of the appropriate type in your constructor, which means that the type of the objects you store in your collection will have their types checked at the point they are added to the collection.

@Esko 2009-02-09 17:46:55

You could create an Object array and cast it to E everywhere. Yeah, it's not very clean way to do it but it should at least work.

@gparyani 2014-09-16 15:46:28

"We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is correct, ideally with citations. Answers without explanations may be removed."

@RamPrasadBismil 2016-04-21 08:55:58

BUt that won`t work in some cases like if your generic class wants to implement Comparable interface.

@Esko 2016-04-26 19:03:24

Welcome to seven years ago, I suppose.

@plugwash 2017-07-12 12:52:04

This will not work if you try to return the array from the generic code to a non-generic caller. There will be a head-scrating classcastexception.

@Ola Bini 2009-02-09 17:33:58

The example is using Java reflection to create an array. Doing this is generally not recommended, since it isn't typesafe. Instead, what you should do is just use an internal List, and avoid the array at all.

@Joachim Sauer 2009-02-09 22:41:38

The second example (using Array.newInstance()) is in fact typesafe. This is possible because the type T of the Class object needs to match the T of the array. It basically forces you to provide the information that the Java runtime discards for generics.

Related Questions

Sponsored Content

76 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 5490208 View
  • 6813 Score
  • 76 Answer
  • Tags:   javascript arrays

33 Answered Questions

[SOLVED] Create ArrayList from array

63 Answered Questions

[SOLVED] How do I generate random integers within a specific range in Java?

  • 2008-12-12 18:20:57
  • user42155
  • 3688276 View
  • 3119 Score
  • 63 Answer
  • Tags:   java random integer

44 Answered Questions

31 Answered Questions

[SOLVED] For-each over an array in JavaScript?

78 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

23 Answered Questions

53 Answered Questions

[SOLVED] Creating a memory leak with Java

30 Answered Questions

[SOLVED] How to append something to an array?

25 Answered Questions

[SOLVED] How do I determine whether an array contains a particular value in Java?

  • 2009-07-15 00:03:21
  • Mike Sickler
  • 1704341 View
  • 2019 Score
  • 25 Answer
  • Tags:   java arrays

Sponsored Content