Here are some follow up questions from a similar query I posted on the general JSDK forum.
It's perfectly valid to have a method with a generic array as a parameter, such as verify(MyClass<String>[] myClasses). Now, if I can receive an array of generics in a method, I must have been able to create them at some point---that reasoning seems perfectly logical to me. Java 5.0 generics apparently doesn't allow creating the array in a type-safe manner, though. Instead, I have to pass new MyClass[10] to the method, which means I lose the type-safety generics was supposed to bring.
In fact, the tutorial by Gilad Bracha (Section 7.3 page 15) says that, "We've had type-safety as a primary design goal of generics. In particular, the language is designed to guarantee that if your entire application has been compiled without unchecked warnings using javac -source 1.5, it is type safe." (emphasis in original) Unfortunately, there's no way to use arrays of generics without unchecked warnings. Even if I cast my array of raw types to an array of generics when I pass it to a method that expects an array of generics, the cast is flagged as an unchecked cast.
I can, however, create a method with varargs (which we all know are implemented as arrays) such as verify(MyClass<String>... myClasses), and then inside the method assign the varargs to an array of MyClass<String>. In fact, I could even create the following utility method:
Won't this create an array of generics for me, with no unchecked warnings? (The problem is that with varargs I have to know at compile time how many items will be in the array when I call the method.)
This all doesn't make sense to me. If a method can have arrays with generics passed as arguments, why can't they be created?
Generic types are compile time types. That's why it's not possible to create an array of generic type, the length of the array is known only at run time.
I propose another solution: replace the array with a collection. You'll have a collection of collection already at compile time and no discussion: It looks like this for a matrix 2x2:
I have a problem with generic array creation.
...
What am I doing wrong ?
There is no generic array creation in Tiger (yet I
keep hoping).
What you can do (but you will get an unpleasant
warning):
T[] pile = (T[]) new Object[255];
I think this will give you not only an "unpleasant" warning,
but also a runtime exception
"ClassCastException" java.lang.ClassCastException: [Ljava.lang.Object;
In general you get a runtime exception doing this in java:
Object[] obs_ok = new String[2];
Object[] obs_ko = new Object[2];
String[] strs;
strs = (String[])obs_ok; // THIS IS OK
strs = (String[])obs_ko; // THIS IS NOT OK
( furthermore, this is a tipical question in java certification exam SCJP !!! : ) )
Generic types are compile time types. That's why it's not possible to create an array of generic type, the length of the array is known only at run time.
Just a minor clarification: it is not the length of the array that is only known at run time, it is the specific type of objects that the array can contain. The amount of memory necessary to contain the array object itself is known when the array is created, and is not a function of the type of objects stored in the array, because the array object doesn't store the actual objects themselves: only constant size references to objects that may or may not exist somewhere in the heap.
Dave Hall
http://jga.sf.net/
http://jroller.com/page/dhall/
I would have thought this would fail to, so I tried it and it actually does work!
Go ahead and try the code below
public class TestGenericArray<T>
{
public static void main(String[] args)
{
TestGenericArray<String> ti = new TestGenericArray<String>();
ti.test("String1","String2");
}
public void test(T... elements)
{
T [] t = (T [])(new Object[elements.length]);
for(int i = 0; i < t.length; i++)
System.out.println((t[i] = elements[i]));
}
}
Generic types are compile time types. That's why it's
not possible to create an array of generic type, the
length of the array is known only at run time.
In a word: no. The fundamental problem is the covariance of arrays.
T0farr - I modified your class - I get a class cast exception at runtime - so I don't think you can simply cast the Object array back to the generic array:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
at collection.TestGenericArray.main(TestGenericArray.java:15)
public class TestGenericArray<T> {
public static void main(String[] args) {
TestGenericArray<String> ti = new TestGenericArray<String>();
String[] a = ti.test("String1", "String2");
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
public T[] test(T... elements) {
T[] t = (T[]) (new Object[elements.length]);
return t;
}
}
This topic has
19
replies
on
2
pages.
1
|
2
|
Next »