//: generics/Holder2.javapublicclassHolder2{privateObjecta;publicHolder2(Objecta){this.a=a;}publicvoidset(Objecta){this.a=a;}publicObjectget(){returna;}publicstaticvoidmain(String[]args){Holder2h2=newHolder2(newAutomobile());Automobilea=(Automobile)h2.get();h2.set("Not an Automobile");Strings=(String)h2.get();h2.set(1);// Autoboxes to IntegerIntegerx=(Integer)h2.get();}}///:~
//: generics/LinkedStack.java// A stack implemented with an internal linked structure.publicclassLinkedStack<T>{//Node类privatestaticclassNode<U>{Uitem;Node<U>next;Node(){item=null;next=null;}Node(Uitem,Node<U>next){this.item=item;this.next=next;}booleanend(){returnitem==null&&next==null;}}privateNode<T>top=newNode<T>();// End sentinelpublicvoidpush(Titem){top=newNode<T>(item,top);}publicTpop(){Tresult=top.item;if(!top.end())top=top.next;returnresult;}publicstaticvoidmain(String[]args){LinkedStack<String>lss=newLinkedStack<String>();for(Strings:"Phasers on stun!".split(" "))lss.push(s);Strings;while((s=lss.pop())!=null)System.out.println(s);}}/* Output:stun!onPhasers*///:~
//: generics/RandomList.javaimportjava.util.*;publicclassRandomList<T>{privateArrayList<T>storage=newArrayList<T>();privateRandomrand=newRandom(47);publicvoidadd(Titem){storage.add(item);}publicTselect(){returnstorage.get(rand.nextInt(storage.size()));}publicstaticvoidmain(String[]args){RandomList<String>rs=newRandomList<String>();for(Strings:("The quick brown fox jumped over "+"the lazy brown dog").split(" "))rs.add(s);for(inti=0;i<11;i++)System.out.print(rs.select()+" ");}}/* Output:brown over fox quick quick dog brown The brown lazy brown*///:~
//: generics/coffee/CoffeeGenerator.java// Generate different types of Coffee:packagegenerics.coffee;importjava.util.*;importnet.mindview.util.*;publicclassCoffeeGeneratorimplementsGenerator<Coffee>,Iterable<Coffee>{privateClass[]types={Latte.class,Mocha.class,Cappuccino.class,Americano.class,Breve.class,};privatestaticRandomrand=newRandom(47);publicCoffeeGenerator(){}// For iteration:privateintsize=0;publicCoffeeGenerator(intsz){size=sz;}publicCoffeenext(){try{//随机生成一种类型return(Coffee)types[rand.nextInt(types.length)].newInstance();// Report programmer errors at run time:}catch(Exceptione){thrownewRuntimeException(e);}}//迭代器classCoffeeIteratorimplementsIterator<Coffee>{intcount=size;publicbooleanhasNext(){returncount>0;}publicCoffeenext(){count--;returnCoffeeGenerator.this.next();}publicvoidremove(){// Not implementedthrownewUnsupportedOperationException();}};publicIterator<Coffee>iterator(){returnnewCoffeeIterator();}publicstaticvoidmain(String[]args){CoffeeGeneratorgen=newCoffeeGenerator();for(inti=0;i<5;i++)System.out.println(gen.next());for(Coffeec:newCoffeeGenerator(5))System.out.println(c);}}/* Output:Americano 0Latte 1Americano 2Mocha 3Mocha 4Breve 5Americano 6Latte 7Cappuccino 8Cappuccino 9*///:~
//: net/mindview/util/New.java// Utilities to simplify generic container creation// by using type argument inference.packagenet.mindview.util;importjava.util.*;publicclassNew{publicstatic<K,V>Map<K,V>map(){returnnewHashMap<K,V>();}publicstatic<T>List<T>list(){returnnewArrayList<T>();}publicstatic<T>LinkedList<T>lList(){returnnewLinkedList<T>();}publicstatic<T>Set<T>set(){returnnewHashSet<T>();}publicstatic<T>Queue<T>queue(){returnnewLinkedList<T>();}// Examples:publicstaticvoidmain(String[]args){Map<String,List<String>>sls=New.map();List<String>ls=New.list();LinkedList<String>lls=New.lList();Set<String>ss=New.set();Queue<String>qs=New.queue();}}///:~
//: generics/SimplerPets.javaimporttypeinfo.pets.*;importjava.util.*;importnet.mindview.util.*;publicclassSimplerPets{publicstaticvoidmain(String[]args){Map<Person,List<?extendsPet>>petPeople=New.map();// Rest of the code is the same...}}///:~
//: generics/LimitsOfInference.javaimporttypeinfo.pets.*;importjava.util.*;publicclassLimitsOfInference{staticvoidf(Map<Person,List<?extendsPet>>petPeople){}publicstaticvoidmain(String[]args){// f(New.map()); // Does not compile}}///:~
//: generics/GenericVarargs.javaimportjava.util.*;publicclassGenericVarargs{publicstatic<T>List<T>makeList(T...args){List<T>result=newArrayList<T>();for(Titem:args)result.add(item);returnresult;}publicstaticvoidmain(String[]args){List<String>ls=makeList("A");System.out.println(ls);ls=makeList("A","B","C");System.out.println(ls);ls=makeList("ABCDEFFHIJKLMNOPQRSTUVWXYZ".split(""));System.out.println(ls);}}/* Output:[A][A, B, C][, A, B, C, D, E, F, F, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]*///:~
//: net/mindview/util/BasicGenerator.java// Automatically create a Generator, given a class// with a default (no-arg) constructor.packagenet.mindview.util;publicclassBasicGenerator<T>implementsGenerator<T>{privateClass<T>type;publicBasicGenerator(Class<T>type){this.type=type;}publicTnext(){try{// Assumes type is a public class:returntype.newInstance();//采用默认构造函数}catch(Exceptione){thrownewRuntimeException(e);}}// Produce a Default generator given a type token:publicstatic<T>Generator<T>create(Class<T>type){returnnewBasicGenerator<T>(type);}}///:~
//: net/mindview/util/Tuple.java// Tuple library using type argument inference.packagenet.mindview.util;publicclassTuple{publicstatic<A,B>TwoTuple<A,B>tuple(Aa,Bb){returnnewTwoTuple<A,B>(a,b);}publicstatic<A,B,C>ThreeTuple<A,B,C>tuple(Aa,Bb,Cc){returnnewThreeTuple<A,B,C>(a,b,c);}publicstatic<A,B,C,D>FourTuple<A,B,C,D>tuple(Aa,Bb,Cc,Dd){returnnewFourTuple<A,B,C,D>(a,b,c,d);}publicstatic<A,B,C,D,E>FiveTuple<A,B,C,D,E>tuple(Aa,Bb,Cc,Dd,Ee){returnnewFiveTuple<A,B,C,D,E>(a,b,c,d,e);}}///:~
//: net/mindview/util/Sets.javapackagenet.mindview.util;importjava.util.*;publicclassSets{//两个集合合并publicstatic<T>Set<T>union(Set<T>a,Set<T>b){Set<T>result=newHashSet<T>(a);result.addAll(b);returnresult;}//共有部分publicstatic<T>Set<T>intersection(Set<T>a,Set<T>b){Set<T>result=newHashSet<T>(a);result.retainAll(b);returnresult;}//移除subset中的元素// Subtract subset from superset:publicstatic<T>Set<T>difference(Set<T>superset,Set<T>subset){Set<T>result=newHashSet<T>(superset);result.removeAll(subset);returnresult;}// Reflexive--everything not in the intersection:publicstatic<T>Set<T>complement(Set<T>a,Set<T>b){returndifference(union(a,b),intersection(a,b));}}///:~
publicclasstypeinfo.SimpleHolder{publictypeinfo.SimpleHolder();Code:0:aload_01:invokespecial#1// Method java/lang/Object."<init>":()V4:returnpublicvoidset(java.lang.Object);Code:0:aload_01:aload_12:putfield#2// Field obj:Ljava/lang/Object;5:returnpublicjava.lang.Objectget();Code:0:aload_01:getfield#2// Field obj:Ljava/lang/Object;4:areturnpublicstaticvoidmain(java.lang.String[]);Code:0:new#3// class typeinfo/SimpleHolder3:dup4:invokespecial#4// Method "<init>":()V7:astore_18:aload_19:ldc#5// String Item11:invokevirtual#6// Method set:(Ljava/lang/Object;)V14:aload_115:invokevirtual#7// Method get:()Ljava/lang/Object;18:checkcast#8// class java/lang/String21:astore_222:return}
publicclasstypeinfo.GenericHolder<T>{publictypeinfo.GenericHolder();Code:0:aload_01:invokespecial#1// Method java/lang/Object."<init>":()V4:returnpublicvoidset(T);Code:0:aload_01:aload_12:putfield#2// Field obj:Ljava/lang/Object;5:returnpublicTget();Code:0:aload_01:getfield#2// Field obj:Ljava/lang/Object;4:areturnpublicstaticvoidmain(java.lang.String[]);Code:0:new#3// class typeinfo/GenericHolder3:dup4:invokespecial#4// Method "<init>":()V7:astore_18:aload_19:ldc#5// String Item11:invokevirtual#6// Method set:(Ljava/lang/Object;)V14:aload_115:invokevirtual#7// Method get:()Ljava/lang/Object;18:checkcast#8// class java/lang/String21:astore_222:return}
//: generics/InstantiateGenericType.cpp// C++, not Java!template<classT>classFoo{Tx;// Create a field of type TT*y;// Pointer to Tpublic:// Initialize the pointer:Foo(){y=newT();}};classBar{};intmain(){Foo<Bar>fb;Foo<int>fi;// ... and it works with primitives}///:~
//: generics/ArrayOfGeneric.javapublicclassArrayOfGeneric{staticfinalintSIZE=100;staticGeneric<Integer>[]gia;@SuppressWarnings("unchecked")publicstaticvoidmain(String[]args){// 可以将子类转换为父类,但不能讲父类转换为子类 所以这里创建Object数组也是不可以的// Compiles; produces ClassCastException://! gia = (Generic<Integer>[])new Object[SIZE];// Runtime type is the raw (erased) type:gia=(Generic<Integer>[])newGeneric[SIZE];System.out.println(gia.getClass().getSimpleName());gia[0]=newGeneric<Integer>();//! gia[1] = new Object(); // Compile-time error// Discovers type mismatch at compile time://! gia[2] = new Generic<Double>();}}/* Output:Generic[]*///:~
//: generics/GenericArray.javapublicclassGenericArray<T>{privateT[]array;@SuppressWarnings("unchecked")publicGenericArray(intsz){array=(T[])newObject[sz];}publicvoidput(intindex,Titem){array[index]=item;}publicTget(intindex){returnarray[index];}// Method that exposes the underlying representation:publicT[]rep(){returnarray;}publicstaticvoidmain(String[]args){GenericArray<Integer>gai=newGenericArray<Integer>(10);// This causes a ClassCastException://! Integer[] ia = gai.rep();// This is OK:Object[]oa=gai.rep();}}///:~
//: generics/GenericArrayWithTypeToken.javaimportjava.lang.reflect.*;publicclassGenericArrayWithTypeToken<T>{privateT[]array;@SuppressWarnings("unchecked")publicGenericArrayWithTypeToken(Class<T>type,intsz){array=(T[])Array.newInstance(type,sz);}publicvoidput(intindex,Titem){array[index]=item;}publicTget(intindex){returnarray[index];}// Expose the underlying representation:publicT[]rep(){returnarray;}publicstaticvoidmain(String[]args){GenericArrayWithTypeToken<Integer>gai=newGenericArrayWithTypeToken<Integer>(Integer.class,10);// This now works:Integer[]ia=gai.rep();}}///:~
//: generics/BasicBounds.javainterfaceHasColor{java.awt.ColorgetColor();}classColored<TextendsHasColor>{Titem;Colored(Titem){this.item=item;}TgetItem(){returnitem;}// The bound allows you to call a method:java.awt.Colorcolor(){returnitem.getColor();}}classDimension{publicintx,y,z;}//类必须在前// This won't work -- class must be first, then interfaces:// class ColoredDimension<T extends HasColor & Dimension> {// Multiple bounds:classColoredDimension<TextendsDimension&HasColor>{Titem;ColoredDimension(Titem){this.item=item;}TgetItem(){returnitem;}java.awt.Colorcolor(){returnitem.getColor();}intgetX(){returnitem.x;}intgetY(){returnitem.y;}intgetZ(){returnitem.z;}}interfaceWeight{intweight();}// As with inheritance, you can have only one// concrete class but multiple interfaces:classSolid<TextendsDimension&HasColor&Weight>{Titem;Solid(Titem){this.item=item;}TgetItem(){returnitem;}java.awt.Colorcolor(){returnitem.getColor();}intgetX(){returnitem.x;}intgetY(){returnitem.y;}intgetZ(){returnitem.z;}intweight(){returnitem.weight();}}classBoundedextendsDimensionimplementsHasColor,Weight{publicjava.awt.ColorgetColor(){returnnull;}publicintweight(){return0;}}publicclassBasicBounds{publicstaticvoidmain(String[]args){Solid<Bounded>solid=newSolid<Bounded>(newBounded());solid.color();solid.getY();solid.weight();}}///:~
//: generics/EpicBattle.java// Demonstrating bounds in Java generics.importjava.util.*;interfaceSuperPower{}interfaceXRayVisionextendsSuperPower{voidseeThroughWalls();}interfaceSuperHearingextendsSuperPower{voidhearSubtleNoises();}interfaceSuperSmellextendsSuperPower{voidtrackBySmell();}classSuperHero<POWERextendsSuperPower>{POWERpower;SuperHero(POWERpower){this.power=power;}POWERgetPower(){returnpower;}}classSuperSleuth<POWERextendsXRayVision>extendsSuperHero<POWER>{SuperSleuth(POWERpower){super(power);}voidsee(){power.seeThroughWalls();}}classCanineHero<POWERextendsSuperHearing&SuperSmell>extendsSuperHero<POWER>{CanineHero(POWERpower){super(power);}voidhear(){power.hearSubtleNoises();}voidsmell(){power.trackBySmell();}}classSuperHearSmellimplementsSuperHearing,SuperSmell{publicvoidhearSubtleNoises(){}publicvoidtrackBySmell(){}}classDogBoyextendsCanineHero<SuperHearSmell>{DogBoy(){super(newSuperHearSmell());}}publicclassEpicBattle{// Bounds in generic methods:static<POWERextendsSuperHearing>voiduseSuperHearing(SuperHero<POWER>hero){hero.getPower().hearSubtleNoises();}static<POWERextendsSuperHearing&SuperSmell>voidsuperFind(SuperHero<POWER>hero){hero.getPower().hearSubtleNoises();hero.getPower().trackBySmell();}publicstaticvoidmain(String[]args){DogBoydogBoy=newDogBoy();useSuperHearing(dogBoy);superFind(dogBoy);// You can do this:List<?extendsSuperHearing>audioBoys;// But you can't do this:// List<? extends SuperHearing & SuperSmell> dogBoys;}}///:~
//: generics/CovariantArrays.javaclassFruit{}classAppleextendsFruit{}classJonathanextendsApple{}classOrangeextendsFruit{}publicclassCovariantArrays{publicstaticvoidmain(String[]args){Fruit[]fruit=newApple[10];fruit[0]=newApple();// OKfruit[1]=newJonathan();// OK// Runtime type is Apple[], not Fruit[] or Orange[]:try{// Compiler allows you to add Fruit:fruit[0]=newFruit();// ArrayStoreException}catch(Exceptione){System.out.println(e);}try{// Compiler allows you to add Oranges:fruit[0]=newOrange();// ArrayStoreException}catch(Exceptione){System.out.println(e);}}}/* Output:java.lang.ArrayStoreException: Fruitjava.lang.ArrayStoreException: Orange*///:~
//: generics/GenericsAndCovariance.javaimportjava.util.*;publicclassGenericsAndCovariance{publicstaticvoidmain(String[]args){// Wildcards allow covariance:List<?extendsFruit>flist=newArrayList<Apple>();// Compile Error: can't add any type of object:// flist.add(new Apple());// flist.add(new Fruit());// flist.add(new Object());flist.add(null);// Legal but uninteresting// We know that it returns at least Fruit:Fruitf=flist.get(0);}}///:~
//: generics/CompilerIntelligence.javaimportjava.util.*;publicclassCompilerIntelligence{publicstaticvoidmain(String[]args){List<?extendsFruit>flist=Arrays.asList(newApple());Applea=(Apple)flist.get(0);// No warningflist.contains(newApple());// Argument is 'Object'flist.indexOf(newApple());// Argument is 'Object'}}///:~
//: generics/GenericReading.javaimportjava.util.*;publicclassGenericReading{static<T>TreadExact(List<T>list){returnlist.get(0);}staticList<Apple>apples=Arrays.asList(newApple());staticList<Fruit>fruit=Arrays.asList(newFruit());// A static method adapts to each call:staticvoidf1(){Applea=readExact(apples);Fruitf=readExact(fruit);f=readExact(apples);}// If, however, you have a class, then its type is// established when the class is instantiated:staticclassReader<T>{TreadExact(List<T>list){returnlist.get(0);}}staticvoidf2(){Reader<Fruit>fruitReader=newReader<Fruit>();Fruitf=fruitReader.readExact(fruit);// Fruit a = fruitReader.readExact(apples); // Error:// readExact(List<Fruit>) cannot be// applied to (List<Apple>).}staticclassCovariantReader<T>{TreadCovariant(List<?extendsT>list){returnlist.get(0);}}staticvoidf3(){CovariantReader<Fruit>fruitReader=newCovariantReader<Fruit>();Fruitf=fruitReader.readCovariant(fruit);Fruita=fruitReader.readCovariant(apples);}publicstaticvoidmain(String[]args){f1();f2();f3();}}///:~
//: generics/Wildcards.java// Exploring the meaning of wildcards.publicclassWildcards{// Raw argument:staticvoidrawArgs(Holderholder,Objectarg){// 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:Objectobj=holder.get();}// Similar to rawArgs(), but errors instead of warnings:staticvoidunboundedArg(Holder<?>holder,Objectarg){// holder.set(arg); // Error:// set(capture of ?) in Holder<capture of ?>// 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:Objectobj=holder.get();}static<T>Texact1(Holder<T>holder){Tt=holder.get();returnt;}static<T>Texact2(Holder<T>holder,Targ){holder.set(arg);Tt=holder.get();returnt;}static<T>TwildSubtype(Holder<?extendsT>holder,Targ){// holder.set(arg); // Error:// set(capture of ? extends T) in// Holder<capture of ? extends T>// cannot be applied to (T)Tt=holder.get();returnt;}static<T>voidwildSupertype(Holder<?superT>holder,Targ){holder.set(arg);// T t = holder.get(); // Error:// Incompatible types: found Object, required T// OK, but type information has been lost:Objectobj=holder.get();}publicstaticvoidmain(String[]args){Holderraw=newHolder<Long>();// Or:raw=newHolder();Holder<Long>qualified=newHolder<Long>();Holder<?>unbounded=newHolder<Long>();Holder<?extendsLong>bounded=newHolder<Long>();Longlng=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<T>// Unchecked method invocation: exact1(Holder<T>)// is applied to (Holder)Longr2=exact1(qualified);Objectr3=exact1(unbounded);// Must return ObjectLongr4=exact1(bounded);// Long r5 = exact2(raw, lng); // Warnings:// Unchecked conversion from Holder to Holder<Long>// Unchecked method invocation: exact2(Holder<T>,T)// is applied to (Holder,Long)Longr6=exact2(qualified,lng);// Long r7 = exact2(unbounded, lng); // Error:// exact2(Holder<T>,T) cannot be applied to// (Holder<capture of ?>,Long)// Long r8 = exact2(bounded, lng); // Error:// exact2(Holder<T>,T) cannot be applied// to (Holder<capture of ? extends Long>,Long)// Long r9 = wildSubtype(raw, lng); // Warnings:// Unchecked conversion from Holder// to Holder<? extends Long>// Unchecked method invocation:// wildSubtype(Holder<? extends T>,T) is// applied to (Holder,Long)Longr10=wildSubtype(qualified,lng);// OK, but can only return Object:Objectr11=wildSubtype(unbounded,lng);Longr12=wildSubtype(bounded,lng);// wildSupertype(raw, lng); // Warnings:// Unchecked conversion from Holder// to Holder<? super Long>// Unchecked method invocation:// wildSupertype(Holder<? super T>,T)// is applied to (Holder,Long)wildSupertype(qualified,lng);// wildSupertype(unbounded, lng); // Error:// wildSupertype(Holder<? super T>,T) cannot be// applied to (Holder<capture of ?>,Long)// wildSupertype(bounded, lng); // Error:// wildSupertype(Holder<? super T>,T) cannot be// applied to (Holder<capture of ? extends Long>,Long)}}///:~
//: generics/CaptureConversion.javapublicclassCaptureConversion{static<T>voidf1(Holder<T>holder){Tt=holder.get();System.out.println(t.getClass().getSimpleName());}staticvoidf2(Holder<?>holder){f1(holder);// Call with captured type}@SuppressWarnings("unchecked")publicstaticvoidmain(String[]args){Holderraw=newHolder<Integer>(1);// f1(raw); // Produces warningsf2(raw);// No warningsHolderrawBasic=newHolder();rawBasic.set(newObject());// Warningf2(rawBasic);// No warnings// Upcast to Holder<?>, still figures it out:Holder<?>wildcarded=newHolder<Double>(1.0);f2(wildcarded);}}/* Output:IntegerObjectDouble*///:~
//: generics/SelfBounding.javaclassSelfBounded<TextendsSelfBounded<T>>{Telement;SelfBounded<T>set(Targ){element=arg;returnthis;}Tget(){returnelement;}}classAextendsSelfBounded<A>{}classBextendsSelfBounded<A>{}// Also OKclassCextendsSelfBounded<C>{CsetAndGet(Carg){set(arg);returnget();}}classD{}// Can't do this:// class E extends SelfBounded<D> {}// Compile error: Type parameter D is not within its bound// Alas, you can do this, so you can't force the idiom:classFextendsSelfBounded{}publicclassSelfBounding{publicstaticvoidmain(String[]args){Aa=newA();a.set(newA());a=a.set(newA()).get();a=a.get();Cc=newC();c=c.setAndGet(newC());}}///:~
//: generics/NotSelfBounded.javapublicclassNotSelfBounded<T>{Telement;NotSelfBounded<T>set(Targ){element=arg;returnthis;}Tget(){returnelement;}}classA2extendsNotSelfBounded<A2>{}classB2extendsNotSelfBounded<A2>{}classC2extendsNotSelfBounded<C2>{C2setAndGet(C2arg){set(arg);returnget();}}classD2{}// Now this is OK:classE2extendsNotSelfBounded<D2>{}///:~
//: generics/CovariantReturnTypes.javaclassBase{}classDerivedextendsBase{}interfaceOrdinaryGetter{Baseget();}interfaceDerivedGetterextendsOrdinaryGetter{// Return type of overridden method is allowed to vary:Derivedget();}publicclassCovariantReturnTypes{voidtest(DerivedGetterd){Derivedd2=d.get();}}///:~
//: generics/GenericsAndReturnTypes.javainterfaceGenericGetter<TextendsGenericGetter<T>>{Tget();}interfaceGetterextendsGenericGetter<Getter>{}publicclassGenericsAndReturnTypes{voidtest(Getterg){Getterresult=g.get();GenericGettergg=g.get();// Also the base type}}///:~
//: generics/SelfBoundingAndCovariantArguments.javainterfaceSelfBoundSetter<TextendsSelfBoundSetter<T>>{voidset(Targ);}interfaceSetterextendsSelfBoundSetter<Setter>{}publicclassSelfBoundingAndCovariantArguments{voidtestA(Setters1,Setters2,SelfBoundSettersbs){s1.set(s2);// s1.set(sbs); // Error:// set(Setter) in SelfBoundSetter<Setter>// cannot be applied to (SelfBoundSetter)}}///:~
//: generics/PlainGenericInheritance.javaclassGenericSetter<T>{// Not self-boundedvoidset(Targ){System.out.println("GenericSetter.set(Base)");}}classDerivedGSextendsGenericSetter<Base>{voidset(Derivedderived){System.out.println("DerivedGS.set(Derived)");}}publicclassPlainGenericInheritance{publicstaticvoidmain(String[]args){Basebase=newBase();Derivedderived=newDerived();DerivedGSdgs=newDerivedGS();dgs.set(derived);dgs.set(base);// Compiles: overloaded, not overridden!}}/* Output:DerivedGS.set(Derived)GenericSetter.set(Base)*///:~
//: generics/CheckedList.java// Using Collection.checkedList().importtypeinfo.pets.*;importjava.util.*;publicclassCheckedList{@SuppressWarnings("unchecked")staticvoidoldStyleMethod(ListprobablyDogs){probablyDogs.add(newCat());}publicstaticvoidmain(String[]args){List<Dog>dogs1=newArrayList<Dog>();oldStyleMethod(dogs1);// Quietly accepts a CatList<Dog>dogs2=Collections.checkedList(newArrayList<Dog>(),Dog.class);try{oldStyleMethod(dogs2);// Throws an exception}catch(Exceptione){System.out.println(e);}// Derived types work fine:List<Pet>pets=Collections.checkedList(newArrayList<Pet>(),Pet.class);pets.add(newDog());pets.add(newCat());}}/* Output:java.lang.ClassCastException: Attempt to insert class typeinfo.pets.Cat element into collection with element type class typeinfo.pets.Dog*///:~
//: generics/decorator/Decoration.javapackagegenerics.decorator;importjava.util.*;classBasic{privateStringvalue;publicvoidset(Stringval){value=val;}publicStringget(){returnvalue;}}classDecoratorextendsBasic{protectedBasicbasic;publicDecorator(Basicbasic){this.basic=basic;}publicvoidset(Stringval){basic.set(val);}publicStringget(){returnbasic.get();}}classTimeStampedextendsDecorator{privatefinallongtimeStamp;publicTimeStamped(Basicbasic){super(basic);timeStamp=newDate().getTime();}publiclonggetStamp(){returntimeStamp;}}classSerialNumberedextendsDecorator{privatestaticlongcounter=1;privatefinallongserialNumber=counter++;publicSerialNumbered(Basicbasic){super(basic);}publiclonggetSerialNumber(){returnserialNumber;}}publicclassDecoration{publicstaticvoidmain(String[]args){TimeStampedt=newTimeStamped(newBasic());TimeStampedt2=newTimeStamped(newSerialNumbered(newBasic()));//! t2.getSerialNumber(); // Not availableSerialNumbereds=newSerialNumbered(newBasic());SerialNumbereds2=newSerialNumbered(newTimeStamped(newBasic()));//! s2.getStamp(); // Not available}}///:~
//: generics/DynamicProxyMixin.javaimportjava.lang.reflect.*;importjava.util.*;importnet.mindview.util.*;import staticnet.mindview.util.Tuple.*;classMixinProxyimplementsInvocationHandler{Map<String,Object>delegatesByMethod;publicMixinProxy(TwoTuple<Object,Class<?>>...pairs){delegatesByMethod=newHashMap<String,Object>();for(TwoTuple<Object,Class<?>>pair:pairs){for(Methodmethod:pair.second.getMethods()){StringmethodName=method.getName();// The first interface in the map// implements the method.if(!delegatesByMethod.containsKey(methodName))delegatesByMethod.put(methodName,pair.first);}}}publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{StringmethodName=method.getName();Objectdelegate=delegatesByMethod.get(methodName);returnmethod.invoke(delegate,args);}@SuppressWarnings("unchecked")publicstaticObjectnewInstance(TwoTuple...pairs){Class[]interfaces=newClass[pairs.length];for(inti=0;i<pairs.length;i++){interfaces[i]=(Class)pairs[i].second;}ClassLoadercl=pairs[0].first.getClass().getClassLoader();returnProxy.newProxyInstance(cl,interfaces,newMixinProxy(pairs));}}publicclassDynamicProxyMixin{publicstaticvoidmain(String[]args){Objectmixin=MixinProxy.newInstance(tuple(newBasicImp(),Basic.class),tuple(newTimeStampedImp(),TimeStamped.class),tuple(newSerialNumberedImp(),SerialNumbered.class));Basicb=(Basic)mixin;TimeStampedt=(TimeStamped)mixin;SerialNumbereds=(SerialNumbered)mixin;b.set("Hello");System.out.println(b.get());System.out.println(t.getStamp());System.out.println(s.getSerialNumber());}}/* Output: (Sample)Hello11325191370151*///:~