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?
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.
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();
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With