Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type safety: Unchecked cast from Object to List<MyObject>

Tags:

I have a ListView listing a custom object (let's say MyObject).

I want to filter it dynamically through an EditText so I had to implement a getFilter() with a publishResults method:

@Override protected void publishResults(CharSequence constraint, FilterResults results) {     MyObjectAdapter.this.setItems((List<MyObject>) results.values);     MyObjectAdapter.this.notifyDataSetChanged(); } 

At this point, Eclipse complains: Type safety: Unchecked cast from Object to List<MyObject>

I am sure this cast will always be true, but Eclipse only suggests to add @SuppressWarnings("unchecked") but I'm totally against SuppressWarnings because it's only hiding the problem, not a solution...

I tried adding:

if(results.values instanceof List<MyObject>) 

But Eclipse complains again, and this solves nothing...

Cannot perform instanceof check against parameterized type List<MyObject>. Use the form List<?>

I know the casting will always be correct, but which is the proper way to make the code to be sure results.values is actually a List<MyObject> ?

Thanks in advance!

like image 525
Eloi Navarro Avatar asked Feb 01 '13 09:02

Eloi Navarro


People also ask

What is unchecked type cast?

What Does the “unchecked cast” Warning Mean? The “unchecked cast” is a compile-time warning. Simply put, we'll see this warning when casting a raw type to a parameterized type without type checking. An example can explain it straightforwardly.

What is an unchecked cast in Java?

Unchecked cast means that you are (implicitly or explicitly) casting from a generic type to a nonqualified type or the other way around.

What is unchecked assignment in Java?

Unchecked assignment: 'java.util.List' to 'java.util.List<java.lang.String>' It means that you try to assign not type safe object to a type safe variable. If you are make sure that such assignment is type safe, you can disable the warning using @SuppressWarnings annotation, as in the following examples.


2 Answers

If all you have to work from is an Object, then you can't check at runtime that you actually have a List<MyObject>, because the generic type MyObject is only used for compile-time type checking, it is not available at runtime. This is why you get an error when you try to add the instanceof check.

If you are sure that your Object really is always a List<MyObject> then I'd say the @SuppressWarnings is OK, if you document why you are sure it is not a problem.

If you absolutely want to avoid a warning though, you could create your own List implementation (say, MyObjectList) that is not itself generic but implements List<MyObject>. Then you can do an instanceof check against MyObjectList at runtime.

Another option is to check for and cast to List<?> as the instanceof error suggests. Then you can iterate over the elements in the list and check if they are actually all instances of MyObject, and copy them to a new List<MyObject>.

like image 156
Medo42 Avatar answered Sep 19 '22 15:09

Medo42


Well, I finally managed to find a solution.

Just as @Medo42 said:

Another option is to check for and cast to List as the instanceof error suggests. Then you can iterate over the elements in the list and check if they are actually all instances of MyObject, and copy them to a new List.

Even though I did not went through the process of creating a whole new object in order to make this particular case to work "warning-less" this was the right direction to go.

So I took @lokoko 's idea and use it in a new setItems() method, with an Object parameter instead of a List<MyObject> in order to make sure

The result code is the following:

public void setItems(List<MyObject> var){     this.list = var; }  public void setItems(Object var){     List<MyObject> result = new ArrayList<MyObject>();     if (var instanceof List){         for(int i = 0; i < ((List<?>)var).size(); i++){             Object item = ((List<?>) var).get(i);             if(item instanceof MyObject){                 result.add((MyObject) item);             }         }     }     setItems(result); } 

Thanks everyone for your help!

like image 21
Eloi Navarro Avatar answered Sep 19 '22 15:09

Eloi Navarro