//: generics/Wildcards.java // Exploring the meaning of wildcards. public class Wildcards { // Raw argument: static void rawArgs(Holder holder, Object arg) { // holder.set(arg); // Warning: // Unchecked call to set(T) as a // member of the raw type Holder // holder.set(new Wildcards()); // Same warning // Can't do this; don't have any 'T': // T t = holder.get(); // OK, but type information has been lost: Object obj = holder.get(); } // Similar to rawArgs(), but errors instead of warnings: static void unboundedArg(Holder holder, Object arg) { // holder.set(arg); // Error: // set(capture of ?) in Holder // cannot be applied to (Object) // holder.set(new Wildcards()); // Same error // Can't do this; don't have any 'T': // T t = holder.get(); // OK, but type information has been lost: Object obj = holder.get(); } static T exact1(Holder holder) { T t = holder.get(); return t; } static T exact2(Holder holder, T arg) { holder.set(arg); T t = holder.get(); return t; } static T wildSubtype(Holder holder, T arg) { // holder.set(arg); // Error: // set(capture of ? extends T) in // Holder // cannot be applied to (T) T t = holder.get(); return t; } static void wildSupertype(Holder holder, T arg) { holder.set(arg); // T t = holder.get(); // Error: // Incompatible types: found Object, required T // OK, but type information has been lost: Object obj = holder.get(); } public static void main(String[] args) { Holder raw = new Holder(); // Or: raw = new Holder(); Holder qualified = new Holder(); Holder unbounded = new Holder(); Holder 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); // Warnings: // Unchecked conversion from Holder to Holder // Unchecked method invocation: exact1(Holder) // is applied to (Holder) Long r2 = exact1(qualified); Object r3 = exact1(unbounded); // Must return Object Long r4 = exact1(bounded); // Long r5 = exact2(raw, lng); // Warnings: // Unchecked conversion from Holder to Holder // Unchecked method invocation: exact2(Holder,T) // is applied to (Holder,Long) Long r6 = exact2(qualified, lng); // Long r7 = exact2(unbounded, lng); // Error: // exact2(Holder,T) cannot be applied to // (Holder,Long) // Long r8 = exact2(bounded, lng); // Error: // exact2(Holder,T) cannot be applied // to (Holder,Long) // Long r9 = wildSubtype(raw, lng); // Warnings: // Unchecked conversion from Holder // to Holder // Unchecked method invocation: // wildSubtype(Holder,T) is // applied to (Holder,Long) Long r10 = wildSubtype(qualified, lng); // OK, but can only return Object: Object r11 = wildSubtype(unbounded, lng); Long r12 = wildSubtype(bounded, lng); // wildSupertype(raw, lng); // Warnings: // Unchecked conversion from Holder // to Holder // Unchecked method invocation: // wildSupertype(Holder,T) // is applied to (Holder,Long) wildSupertype(qualified, lng); // wildSupertype(unbounded, lng); // Error: // wildSupertype(Holder,T) cannot be // applied to (Holder,Long) // wildSupertype(bounded, lng); // Error: // wildSupertype(Holder,T) cannot be // applied to (Holder,Long) } } ///:~