OnJava8-Examples/generics/Wildcards.java
2016-12-30 17:23:13 -08:00

284 lines
9.3 KiB
Java

// generics/Wildcards.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Exploring the meaning of wildcards
public class Wildcards {
// Raw argument:
static void rawArgs(Holder holder, Object arg) {
//- holder.set(arg);
// warning: [unchecked] unchecked call to set(T)
// as a member of the raw type Holder
// holder.set(arg);
// ^
// where T is a type-variable:
// T extends Object declared in class Holder
// 1 warning
// Can't do this; don't have any 'T':
// T t = holder.get();
// OK, but type information is lost:
Object obj = holder.get();
}
// Similar to rawArgs(), but errors instead of warnings:
static void unboundedArg(Holder<?> holder, Object arg) {
//- holder.set(arg);
// error: method set in class Holder<T>
// cannot be applied to given types;
// holder.set(arg);
// ^
// required: CAP#1
// found: Object
// reason: argument mismatch;
// Object cannot be converted to CAP#1
// where T is a type-variable:
// T extends Object declared in class Holder
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Object from capture of ?
// 1 error
// Can't do this; don't have any 'T':
// T t = holder.get();
// OK, but type information is lost:
Object obj = holder.get();
}
static <T> T exact1(Holder<T> holder) {
return holder.get();
}
static <T> T exact2(Holder<T> holder, T arg) {
holder.set(arg);
return holder.get();
}
static <T>
T wildSubtype(Holder<? extends T> holder, T arg) {
//- holder.set(arg);
// error: method set in class Holder<T#2>
// cannot be applied to given types;
// holder.set(arg);
// ^
// required: CAP#1
// found: T#1
// reason: argument mismatch;
// T#1 cannot be converted to CAP#1
// where T#1,T#2 are type-variables:
// T#1 extends Object declared in method
// <T#1>wildSubtype(Holder<? extends T#1>,T#1)
// T#2 extends Object declared in class Holder
// where CAP#1 is a fresh type-variable:
// CAP#1 extends T#1 from capture of ? extends T#1
// 1 error
return holder.get();
}
static <T>
void wildSupertype(Holder<? super T> holder, T arg) {
holder.set(arg);
//- T t = holder.get();
// error: incompatible types:
// CAP#1 cannot be converted to T
// T t = holder.get();
// ^
// where T is a type-variable:
// T extends Object declared in method
// <T>wildSupertype(Holder<? super T>,T)
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Object super:
// T from capture of ? super T
// 1 error
// OK, but type information is lost:
Object obj = holder.get();
}
public static void main(String[] args) {
Holder raw = new Holder<>();
// Or:
raw = new Holder();
Holder<Long> qualified = new Holder<>();
Holder<?> unbounded = new Holder<>();
Holder<? extends Long> bounded = new Holder<>();
Long lng = 1L;
rawArgs(raw, lng);
rawArgs(qualified, lng);
rawArgs(unbounded, lng);
rawArgs(bounded, lng);
unboundedArg(raw, lng);
unboundedArg(qualified, lng);
unboundedArg(unbounded, lng);
unboundedArg(bounded, lng);
//- Object r1 = exact1(raw);
// warning: [unchecked] unchecked method invocation:
// method exact1 in class Wildcards is applied
// to given types
// Object r1 = exact1(raw);
// ^
// required: Holder<T>
// found: Holder
// where T is a type-variable:
// T extends Object declared in
// method <T>exact1(Holder<T>)
// warning: [unchecked] unchecked conversion
// Object r1 = exact1(raw);
// ^
// required: Holder<T>
// found: Holder
// where T is a type-variable:
// T extends Object declared in
// method <T>exact1(Holder<T>)
// 2 warnings
Long r2 = exact1(qualified);
Object r3 = exact1(unbounded); // Must return Object
Long r4 = exact1(bounded);
//- Long r5 = exact2(raw, lng);
// warning: [unchecked] unchecked method invocation:
// method exact2 in class Wildcards is
// applied to given types
// Long r5 = exact2(raw, lng);
// ^
// required: Holder<T>,T
// found: Holder,Long
// where T is a type-variable:
// T extends Object declared in
// method <T>exact2(Holder<T>,T)
// warning: [unchecked] unchecked conversion
// Long r5 = exact2(raw, lng);
// ^
// required: Holder<T>
// found: Holder
// where T is a type-variable:
// T extends Object declared in
// method <T>exact2(Holder<T>,T)
// 2 warnings
Long r6 = exact2(qualified, lng);
//- Long r7 = exact2(unbounded, lng);
// error: method exact2 in class Wildcards
// cannot be applied to given types;
// Long r7 = exact2(unbounded, lng);
// ^
// required: Holder<T>,T
// found: Holder<CAP#1>,Long
// reason: inference variable T has
// incompatible bounds
// equality constraints: CAP#1
// lower bounds: Long
// where T is a type-variable:
// T extends Object declared in
// method <T>exact2(Holder<T>,T)
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Object from capture of ?
// 1 error
//- Long r8 = exact2(bounded, lng);
// error: method exact2 in class Wildcards
// cannot be applied to given types;
// Long r8 = exact2(bounded, lng);
// ^
// required: Holder<T>,T
// found: Holder<CAP#1>,Long
// reason: inference variable T
// has incompatible bounds
// equality constraints: CAP#1
// lower bounds: Long
// where T is a type-variable:
// T extends Object declared in
// method <T>exact2(Holder<T>,T)
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Long from
// capture of ? extends Long
// 1 error
//- Long r9 = wildSubtype(raw, lng);
// warning: [unchecked] unchecked method invocation:
// method wildSubtype in class Wildcards
// is applied to given types
// Long r9 = wildSubtype(raw, lng);
// ^
// required: Holder<? extends T>,T
// found: Holder,Long
// where T is a type-variable:
// T extends Object declared in
// method <T>wildSubtype(Holder<? extends T>,T)
// warning: [unchecked] unchecked conversion
// Long r9 = wildSubtype(raw, lng);
// ^
// required: Holder<? extends T>
// found: Holder
// where T is a type-variable:
// T extends Object declared in
// method <T>wildSubtype(Holder<? extends T>,T)
// 2 warnings
Long r10 = wildSubtype(qualified, lng);
// OK, but can only return Object:
Object r11 = wildSubtype(unbounded, lng);
Long r12 = wildSubtype(bounded, lng);
//- wildSupertype(raw, lng);
// warning: [unchecked] unchecked method invocation:
// method wildSupertype in class Wildcards
// is applied to given types
// wildSupertype(raw, lng);
// ^
// required: Holder<? super T>,T
// found: Holder,Long
// where T is a type-variable:
// T extends Object declared in
// method <T>wildSupertype(Holder<? super T>,T)
// warning: [unchecked] unchecked conversion
// wildSupertype(raw, lng);
// ^
// required: Holder<? super T>
// found: Holder
// where T is a type-variable:
// T extends Object declared in
// method <T>wildSupertype(Holder<? super T>,T)
// 2 warnings
wildSupertype(qualified, lng);
//- wildSupertype(unbounded, lng);
// error: method wildSupertype in class Wildcards
// cannot be applied to given types;
// wildSupertype(unbounded, lng);
// ^
// required: Holder<? super T>,T
// found: Holder<CAP#1>,Long
// reason: cannot infer type-variable(s) T
// (argument mismatch; Holder<CAP#1>
// cannot be converted to Holder<? super T>)
// where T is a type-variable:
// T extends Object declared in
// method <T>wildSupertype(Holder<? super T>,T)
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Object from capture of ?
// 1 error
//- wildSupertype(bounded, lng);
// error: method wildSupertype in class Wildcards
// cannot be applied to given types;
// wildSupertype(bounded, lng);
// ^
// required: Holder<? super T>,T
// found: Holder<CAP#1>,Long
// reason: cannot infer type-variable(s) T
// (argument mismatch; Holder<CAP#1>
// cannot be converted to Holder<? super T>)
// where T is a type-variable:
// T extends Object declared in
// method <T>wildSupertype(Holder<? super T>,T)
// where CAP#1 is a fresh type-variable:
// CAP#1 extends Long from capture of
// ? extends Long
// 1 error
}
}