开发者

Java Generics: Why does an explicit cast cause a compiler error, but variable assignment does not

开发者 https://www.devze.com 2023-02-19 03:40 出处:网络
This block compiles properly: ArrayList<Baz> list = savedInstanceState.getParcelableArrayList(\"foo\");

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消