I've looked around and so far haven't seen any way of having both a lower and upper bound on the same wildcard type in java. I'm not sure if it is possible and am leaning towards it being a current limitation of wildcards in java.
An example of what I'm looking for is below.
public class A {}
public class B extends A{}
public class C extends B{}
public class D extends C{}
public static void main(String[] args)
{
List<A> a = Arrays.asList(new A());
List<B> b = Arrays.asList(new B());
List<C> c = Arrays.asList(new C());
List<D> d = Arrays.asList(new D());
extendsParam(a); // error as A is not assignable to B
extendsParam(b);
extendsParam(c);
extendsParam(d); // 3 previous ok as they can produce B
superParam(a);
superParam(b);
superParam(c); // 3 previous ok as they can consume C
superParam(d); // error as C is not assignable to D
extendsSuperParam(a); // error as A is not assignable to B
extendsSuperParam(b);
extendsSuperParam(c); // 2 previous ok as they can consume C and produce B
extendsSuperParam(d); // error as C is not assignable to D
}
public static void extendsParam(List<? extends B> blist)
{
B b = blist.get(0);
blist.add(new C()); // error
}
public static void superParam(List<? super C> clist)
{
B b = clist.get(0); // error
clist.add(new C());
}
public static void extendsSuperParam(List<???> bclist)
{
B b = bclist.get(0); // ok
bclist.add(new C()); // ok
}
Looking at the WildcardType.java
class for the generic type information it looks like it supports defining a type with that information. However, I cannot find a way to create such a type in the language.
Is there something that I'm missing or is this a type that is currently impossible to describe with the java language?
Advertisements. The question mark (?), represents the wildcard, stands for unknown type in generics. There may be times when you'll want to restrict the kinds of types that are allowed to be passed to a type parameter.
Upper-bound is when you specify (? extends Field) means argument can be any Field or subclass of Field. Lower-bound is when you specify (? super Field) means argument can be any Field or superclass of Field.
The only restriction on wilds cards is that you cannot it as a type argument of a generic method while invoking it.
To declare an upper-bounded wildcard, use the wildcard character ('? '), followed by the extends keyword, followed by its upper bound. Note that, in this context, extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).
Lower Bounded Wildcards. The Upper Bounded Wildcards section shows that an upper bounded wildcard restricts the unknown type to be a specific type or a subtype of that type and is represented using the extends keyword. In a similar way, a lower bounded wildcard restricts the unknown type to be a specific type or a super type...
Types of wildcards in Java: Upper Bounded Wildcards: These wildcards can be used when you want to relax the restrictions on a variable. Lower Bounded Wildcards: It is expressed using the wildcard character (‘?’), followed by the super keyword, followed by its lower bound: <? super A>.
To declare an upper-bounded wildcard, use the wildcard character (‘?’), followed by the extends keyword, followed by its upper bound. In the above program, list1 and list2 are objects of the List class. list1 is a collection of Integer and list2 is a collection of Double.
A lower bounded wildcard is expressed using the wildcard character ('? '), following by the super keyword, followed by its lower bound: <? super A>. Note: You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both. Say you want to write a method that puts Integer objects into a list.
This can't be done according to the Oracle Docs:
Note: You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both.
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