I have declared a method whose argument is subtype of Number
as given below:
public static void organizeData(java.util.List<? extends Number> c) {
//operation on the list
}
I am able to pass any non-parameterized lists as argument. So what is the point of using wildcard <? extends Number>
?
List newList = new LinkedList<>();
ClassName.organizeData(newList);
Why do I get element of type Object
from c
? And not of type Number
? Is there a way to allow only subtypes of a type to be passed as arguments as opposed to allowing non-parameterized arguments also?
You are asking three questions here, I will answer them separately. By the way, you would find it valuable to read the Java Generics FAQ - considered by many to be the canonical reference on the subject:
<? extends Number>
?You need to use the wildcard for the times when the parameterized argument is a subclass of Number
, say, Integer
. For instance:
import java.util.LinkedList;
import java.util.List;
public class NumberTest {
public static void main(String... args) {
List<Integer> newList = new LinkedList<Integer>();
organizeData(newList); // This works!
anotherMethod(newList); // Doesn't compile
}
private static void organizeData(List<? extends Number> list) {
}
private static void anotherMethod(List<Number> list) {
}
}
The second method call fails with the compilation error:
NumberTest.java:9: error: method anotherMethod in class NumberTest cannot be applied to given types;
anotherMethod(newList); // Doesn't compile
^
required: List<Number>
found: List<Integer>
reason: actual argument List<Integer> cannot be converted to List<Number> by method invocation conversion
1 error
Object
from c
? And not of type Number
?The reason you get a type of Object
in your second case is because you are using the Raw Type. You should never use a raw type if you can avoid it for that reason - you lose all the advantages of compiler type checking.
You cannot prevent Heap Pollution in the way you describe because someone can always cast to the Raw type and then to whatever is required. Generics are a compile time only construct, and are ultimately erased after compilation. This is why the Unchecked Type Conversion warning can only be suppressed via annotation.
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