Wild Card Capture
When Evaluating an
expression compiler infers particular type from the code, this is
called Wild card capture. While evaluating any expression, if
compiler found any chance of wrong types, then compiler throws
the error.
Example
import java.util.*;
class Test{
static void combine(List<?> a, List<?> b){
setData(a, b);
}
static <T> void setData(List<T> a, List<T> b){
}
}
When you tries to
compile the above code compiler tries to infer the types and place it
in the expressions.
combine(List<?>
a, List<?> b) is calling the method setData(List<T> a,
List<T> b). Where Parameters in setData has type “T”, which
is called by the method combine(List<?> a, List<?> b).
So combine can be
called like below
combine(List<Integer>
list1, List<Float> list2);
combine(List<Double>
list1, List<String> list2);
since “?” can
accept any type. But the method setData signature is different, It
can able to accept the parameters which is of same type "T". So there is
an ambiguity, so while trying to compile the above program, compiler
throws the below error.
Test.java:6:
error: method setData in class Test cannot be applied to given types;
setData(a, b);
^
required:
List<T>,List<T>
found:
List<CAP#1>,List<CAP#2>
reason:
no instance(s) of type variable(s) T exist so that argument type
List<
CAP#2>
conforms to formal parameter type List<T>
where
T is a type-variable:
T
extends Object declared in method <T>setData(List<T>,List<T>)
where
CAP#1,CAP#2 are fresh type-variables:
CAP#1
extends Object from capture of ?
CAP#2
extends Object from capture of ?
1
error
Below program compiles
fine, since T1 and T2 are two different variables.
import java.util.*;
class Test1{
static void combine(List<?> a, List<?> b){
setData(a, b);
}
static <T1, T2> void setData(List<T1> a, List<T2> b){
}
}
Will see one more
program, to better understand the wild capture.
import java.util.*;
class Test2{
public static void main(String args[]){
List<? extends Number> list1 = new ArrayList<Number> ();
list1.add(10);
}
}
List<? extends
Number> list1: the compiler knows that it, is a List of Number
or some subclass of Number, but it does not know which. Therefore,
you will never be allowed to add anything to such a list. So when
trying to compile the above program compiler throws the below error.
Test2.java:5:
error: no suitable method found for add(int)
list1.add(10);
^
method
List.add(int,CAP#1) is not applicable
(actual
and formal argument lists differ in length)
method
List.add(CAP#1) is not applicable
(actual
argument int cannot be converted to CAP#1 by method invocation
conversion)
where
CAP#1 is a fresh type-variable:
CAP#1
extends Number from capture of ? extends Number
1
error
No comments:
Post a Comment