Java Generics: Why does an explicit cast cause a compiler error, but variable assignment does not
This block compiles properly:
ArrayList<Baz> list = savedInstanceState.getParcelableArrayList("foo");
bar(list);
But this block errors stating that ArrayList<Parcelable>
can not be cast to ArrayList<Baz>
:
bar((ArrayList<Baz>)savedInstanceState.getParcelableArrayList("foo"))
Where bar is of the form:
private void bar(ArrayList<Baz> food) {
}
And Baz
is a class that implements the Parcelable
interface
Is there a way that the direct cast can be do开发者_高级运维ne rather than having to perform an implicit cast and create an unnecessary variable?
In order to use reference the method bar(ArrayList<T> food)
, you must perform a generic type invocation, which replaces T
with some concrete value. T
must be bounded to some type else, introduce wildcards like bar(ArrayList<?> food)
.
- Reference.
Both those blocks are the same. Take this as an example which compiles:
import java.util.ArrayList;
public class Test<T> {
public void test(){
ArrayList<T> list = (ArrayList<T>)foo();
bar(list);
bar((ArrayList<T>)foo());
}
private ArrayList<Integer> foo(){ return null; }
private void bar(ArrayList<T> food) {}
}
I got the same problem, and my solution is to create a method to convert Parcelable to Baz. For example..
private ArrayList<Baz> convertParcelableToBaz(ArrayList<Parcelable> parcelableList){
ArrayList<Baz> bazList= new ArrayList<Baz>();
for (int i = 0 ; i < parcelableList.size(); i++){
bazList.add((Baz)parcelableList.get(i));
}
return bazList;
}
so that
ArrayList<Baz> list = convertParcelableToBaz(savedInstanceState.getParcelableArrayList("foo"));
and no unchecked cast warning.
What is the error that you're getting; I would think that you'll only get a warning stating that it is an unchecked cast. If this is the case, you will need to add @SuppressWarnings("unchecked")
to the function that you're FROM. To be honest; you'd be best to create a separate variable to catch the return value then send the variable.
One of the issues that you'll see here is that Java's type erasure is going to hurt you. If T is declared differently between calling function and receiving function, when T is removed there is nothing that prevents someone from actually sending your function which expects ArrayList an ArrayList. Which is why this is a type safety issue.
精彩评论