Well, hold on a minute. Suppose your hypothesis were correct that String
were substituted for every T
.
Would the following cast be valid?
String[] result = (String[])new Object[s];
No, it would not. We can be sure that a new Object[]
is not a String[]
.
Now sometimes you will see something like (T[])new Object[n]
but it only works because the cast actually becomes erased inside the generic class. (It is a deceptive idiom.)
When the class gets compiled, what actually happens is that references to T
are replaced with its upper bound (probably Object
unless you had something like <T extends ...>
):
public Object[] toArray(){
int s=size();
Object[] result=new Object[s];
Node n=first;
for (int i=0; i<s; i++){
result[i]=n.data;
n=n.next;
}
return result;
}
And the cast is moved to the call site:
MyStack stack = new MyStack();
String[] arr = (String[])stack.toArray();
So in fact, while the cast is erased inside the class, the cast does happen once the value is returned to outside the class, where ClassCastException
is thrown.
The inability to instantiate arrays (and objects in general) generically is why the Collections framework defines their toArray
method to take the return array as an argument. A simple version of this for you would be like the following:
public T[] toArray(T[] inArray){
int s = size();
Node n = first;
for (int i = 0; i < s; i++){
inArray[i] = n.data;
n = n.next;
}
return inArray;
}
For some ideas on how to create an array generically, you may see 'How to create a generic array in Java?'; however you will need the caller to pass some argument to the method.