I'm trying to write a generic method to return the contents of an Iterable in array form.
Here is what I have:
public class IterableHelp
{
public <T> T[] toArray(Iterable<T> elements)
{
ArrayList<T> arrayElements = new ArrayList<T>();
for(T element : elements)
{
arrayElements.add(element);
}
return (T[])arrayElements.toArray();
}
}
But I'm getting a compiler warning 'Note: ...\IterableHelp.java uses unchecked or unsafe operations.'
Any thoughts on another approach that would avoid such a warning?
There isn't a way to get rid of the
unchecked or unsafe operations
warning, or creating a TypeSafe Array without editing your method signature.See this bug report for the gory details.
One way is to pass in a pre-allocated Array of Type
T
:This gets rid of the
unchecked or unsafe
warning, but it also puts the onus on the calling class to create the array with the correct bounds to begin with which kind of defeats the purpose of your convenience method.If you want to dynamically create a TypeSafe array, you really can't do it in a TypeSafe way in Java.
This works and compiles, but it doesn't solve the unchecked or unsafe cast issue, it just moves it to a different place. I had to add the
@SuppressWarnings
annotation to get it to stop complaining about the cast.There's a method
Iterables.toArray
in Google Guava.Looking at the source, it's defined as:
Where
ObjectArrays.newArray
eventually delegates to a method that looks like:So it looks like there's no way to avoid the
@SuppressWarnings
entirely, but you can and should at least constrain it to the smallest possible scope.Or, better yet, just use somebody else's implementation!
You got a bigger problem than the unchecked warning. In fact, it will throw a ClassCastException at runtime if T is anything other than Object.
Try
String[] foo = IterableHelp.toArray(new ArrayList<String>());
Simply put, since arrays contain the component type at runtime, to create a proper T[] you must pass in the component class as another argument (either as the class of T or T[] itself, or as an object of T or T[]), and use reflection to create the array. The form of
Collection
'stoArray()
method that takes an argument, takes in a T[] object for this reason.