class A {}
class B {}
public class Test {
public static void main(String[] args) {
A a = null;
foo(a);
}
public static <T> void foo(T a) {
T[] t = (T[]) new Object[10];
Object[] o = t; // correct. Object[] is parent of T[].
o[0] = new B(); // correct. Insert B into object[].
T val = t[0]; // Type error if T is not A!!
System.out.println(t[0]);
}
}
T[] t = (T[]) new Object[10]; is the way of declaring an array of T
that people in this forum recommend. However, I've found something
quite strange. As you can see in the code above , T must be A. However,
strangely enough, T val = t[0] succeeded. In this code, T is obviously
A, and t[0] is also obviously B. However, JDK raises only one warning
on T[] t = (T[]) new Object[10], saying that "cast from Object[] to T[]
is actually checking against erased type Object[]."
Though the tutorial on generics says that codes are type-safe only when
there's no warning, assigning instance of B into the variable whose
type is A is quite weird.
Is this a bug or my mistake?
Sincerely,
Minkoo Seo
>T[] t = (T[]) new Object[10];
I think the key is that cast is bogus. You can't cast Object[] to T[]
even if all the element in the array are T. You can only do it by
creating a T[] array and copying the elements over.
But from Java' Alice in wonderland view, T[] t isn't really a T[]
after all. it is an Object[] so it doesn't matter that the cast makes
no sense.
I grit my teeth at this stuff. Sometimes type checking is all make
believe.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.
Roedy Green wrote:
> But from Java' Alice in wonderland view, T[] t isn't really a T[]
> after all. it is an Object[] so it doesn't matter that the cast makes
> no sense.
So, do you think that allocating B into the array whose type is A is
okay in this example because the actual storage is declared as
Object[]? I don't think so. What matters here is that the javac behaves
contrary to the intuition.
p.s.
I know that the example I've shown is quite weird. I've made it based
on the codes in Section 7.3, java generics tutorial
(http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf).
Sincerely,
Minkoo Seo
This has been addressed before in the newsgroup. The short answer is,
because of backwards compatibility reasons, Java's generics is not a nice as
we'd like it to be.
"T[] t = (T[]) new Object[10];" is not legal when T refers to A. That is
to say, and array of A is not the same as an array of Object.
- Oliver