I have generic type with Class<T> object provided in constructor. I want to create two-dimensional array T[][] in this constructor, is this however possible?
-
Not in Java, only in languages with runtime generics like C#. Think about erasure.Benjamin Gruenbaum– Benjamin Gruenbaum2013-08-07 18:28:43 +00:00Commented Aug 7, 2013 at 18:28
-
Please post the specific signature of the constructor you're thinking of using. This may be possible, but it's not clear what you're asking.chrylis -cautiouslyoptimistic-– chrylis -cautiouslyoptimistic-2013-08-07 18:30:45 +00:00Commented Aug 7, 2013 at 18:30
-
1Yes, you can use Array.newInstance(). See stackoverflow.com/questions/529085/…. I'd flag as a duplicate but I'm out of flags, can somebody take care of this?Jason C– Jason C2013-08-07 18:31:54 +00:00Commented Aug 7, 2013 at 18:31
-
1@JasonC It's not exactly a duplicate, because this is asking about two-dimensional arrays and the question you linked doesn't seem to have any talk about creating multidimensional instances, which could lead someone to think it only works for one dimension and thus a more complicated procedure would be required than actually is.JAB– JAB2013-08-07 18:40:24 +00:00Commented Aug 7, 2013 at 18:40
-
1It was closed as a duplicate, although I disagree now based on @JAB's comments above. Some of the other answers previously posted here (now deleted) demonstrated a lack of understanding that the 1D case described in the linked question could be extended to 2D - precisely the situation JAB described above. I've attempted to show that in my answer. I actually feel this question should be reopened and the other one be marked as a duplicate of this one, since this is a more general case.Jason C– Jason C2013-08-09 16:57:18 +00:00Commented Aug 9, 2013 at 16:57
|
Show 4 more comments
2 Answers
Same as How to create a generic array in Java? but extended to 2D:
import java.lang.reflect.Array;
public class Example <T> {
private final Class<? extends T> cls;
public Example (Class<? extends T> cls) {
this.cls = cls;
}
public void arrayExample () {
// a [10][20] array
@SuppressWarnings("unchecked")
T[][] array = (T[][])Array.newInstance(cls, 10, 20);
System.out.println(array.length + " " + array[0].length + " " + array.getClass());
}
public static final void main (String[] args) {
new Example<Integer>(Integer.class).arrayExample();
}
}
Note after reading JAB's comment above: To extend to more dimensions, just add []'s and dimension parameters to newInstance() (cls is a Class, 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.
6 Comments
Jason C
I noticed the OP edited the question and added "in this constructor". Same method as above (e.g. move the code from arrayExample() into the constructor).
Krzysztof Stanisławek
Thank you, I didn't know (and I thought that I checked in documentation) that I can use newInstance with more parameters - my fault, I could check this out.
newacct
It is not safe to cast to
T[][] (or whatever). cls may be a primitive type.Jason C
@newacct +1 but I'm out of votes. You would have to do something like
new Example<Integer>(int.class) to get to that point, which is arguably weird, but yes, you are right. I'll update when I get a chance.newacct
@JasonC: well, you could just return
Object instead of a particular type of array. Or at least, the last level of the multidimensional array must be replaced with Object. (So, a two-dimensional array can be safely represented by Object[]; a one-dimensional array can only be represented by Object.) |
You have to use reflection, but it's possible: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Array.html#newInstance%28java.lang.Class,%20int...%29
Creates a new array with the specified component type and dimensions.