Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unchecked assignment warning

I am using Android Studio 1.1.0.

This causes no warning:

public static class A {     public Map<Integer, String> getMap() {         return null;     } }  public static class B {     public void processA(A a) {         Map<Integer, String> map = a.getMap();     } } 

But make A generic:

public static class A<T> {     public Map<Integer, String> getMap() {         return null;     } } 

And this line:

Map<Integer, String> map = a.getMap(); 

gets you a warning now: "Unchecked assignment: 'java.util.Map to java.util.Map<java.lang.Integer, java.lang.String>'.

Even though the signature of getMap is totally independent of T, and the code is unambiguous regarding the types the Map contains.

I know that I can get rid of the warning by reimplementing processA as follows:

public <T> void processA(A<T> a) {     Map<Integer, String> map = a.getMap(); } 

But why would I have to do that? What does T matter here at all?

So, the question is - why does type erasure have to not only affect T (which is understandable - if I'm passing an instance of A, T is an unknown), but also "hardcoded" generic signature like <Integer, String> in this case?

like image 373
Konrad Morawski Avatar asked Mar 02 '15 10:03

Konrad Morawski


People also ask

What is unchecked warning?

An unchecked warning tells a programmer that a cast may cause a program to throw an exception somewhere else. Suppressing the warning with @SuppressWarnings("unchecked") tells the compiler that the programmer believes the code to be safe and won't cause unexpected exceptions.

What does unchecked assignment mean 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. E.g. this line. Set<String> set = new HashSet();

What does the compiler mean by an unchecked call?

The warning tells you that the compiler has encountered a condition that it can't guarantee the sense of. You should avoid having this kind of thing.


1 Answers

In your second case when you do:

public void processA(A a) 

What do you mean by A? Does it mean A<String> or A<List<String>> or what? You might not be using anything related to type of A, but hey the compiler doesn't know this fact. To compiler, just A is a sign of panic.

In your case, because you dont specifically need to know the type of A, you can:

public void processA(A<?> a) {     Map<Integer, String> map = a.getMap(); }  

Having an argument type of A<?> means, you do not specifically care the type of A and just specify a wild card. To you it means: any object of A with any type as its generic type would do. In reality, it means you do not know the type. Its useless because you cannot do anything related to A in typesafe manner as ? can be virtually anything!

But as per your method body, it makes all the sense in the world to use A<?> because no where in the body you actually need the type of A

like image 187
Jatin Avatar answered Oct 12 '22 10:10

Jatin