So I understand that generics and arrays really don't mix well, but I have an assignment where I have to make it work. I need to return the underlying array of a set ADT using the toArray() method, but I'm not allowed to pass in something like Class c that I could use to return the generic array as a specific class type.
So the following would work, but is not allowed:
public T[] toArray(Class<T> c){
@SuppressWarnings("unchecked")
T[] returnContents = (T[]) Array.newInstance(c, size);
for(int i = 0; i<size; i++){
returnContents[i] = contents[i];
}
return returnContents;
}
I can't pass in the class type because the Set class I'm in implements a SetInterface that doesn't have a parameter for the toArray method. Thus I'm being limited to what I can do.
public T[] toArray(){
@SuppressWarnings("unchecked")
T[] returnContents = (T[]) new Object[size];
for(int i = 0; i<size; i++){
returnContents[i] = contents[i];
}
return returnContents;
}
Above is what I have now, which will return an array of type Objects because (if I understand correctly) type erasure don't carry through after compiling.
In my client code, I have the following line that will give me a casting exception
ProfileInterface [] friends = new ProfileInterface[friendsList.getCurrentSize()];
friends = Arrays.copyOf(friendsList.toArray(), friendsList.toArray().length);
friendsList is a generic Set
Any ideas on a work around for this?
If anyone runs into this problem in the future: coughs CS445 Assignment 1
The easiest way to accomplish this without breaking the generic nature of the set class is the following...
As discussed, we need to return the following (or a copy of it in this case)
T[] returnContents = (T[]) new Object[size];
Now, since Java will read the (T[]) at compile time, this is fine - but at run time we can't have a T array, so we use Object.
The problem is you can't cast an Object Array to a ProfileInterface Array in your client code (or any non-generic class for that matter).
So the only solution in a limited set of actions is to deal with the fact that the client can assume that all of the "Objects" in the array will be an Object that implements ProfileInterface (so Profile / ProfileInterface)
So in your client code, you will create a new Object array and iterate through it, casting and setting each individual item in the array as a Profile.
Object[] all = new Object[yourSize];
ProfileInterface [] friends = new ProfileInterface[yourSize];
all = Arrays.copyOf(friendsList.toArray(), friendsList.toArray().length);
for(int i = 0; i < all.length; i ++){
friends[i] = (ProfileInterface) all[i];
}
This will allow you to return the generic toArray to your client and then you can manipulate it.
PLEASE NOTE: This only works in this specific case where you KNOW FOR CERTAIN that no other object type will be returned by your generic class. If you can pass in the class type as a parameter, you very simply fix this problem in the Generic class.