classWildcards { // Raw argument: // Holder是一个泛型类,这里表示称原生类型,但是编译器仍就知道向set传递一个Object是不安全的。 staticvoidrawArgs(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: Objectobj= holder.get(); } // Similar to rawArgs(), but errors instead of warnings: // 这里演示了<?>和原生类型是不同的: staticvoidunboundedArg(Holder<?> holder, Object arg) { // 原生Holder将持有任何类型的组合,而Holder<?>将持有具有某种具体类型的同构集合,因此不能只是向其中传递Object 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> T exact1(Holder<T> holder) { Tt= holder.get(); return t; } static <T> T exact2(Holder<T> holder, T arg) { holder.set(arg); Tt= holder.get(); return t; } // 在Holder类型上的限制被放松为包括持有任何扩展自T的对象的Holder, // 传入了Holder<Apple>之后,为了防止将Orange放置到Holder<Apple>, // 对set的调用都是不允许的,但是你仍旧知道任何来自Holder<? extends Fruit的对象至少是Fruit,因此get()是允许的 static <T> T wildSubtype(Holder<? extends T> holder, T arg) { // holder.set(arg); // Error: // set(capture of ? extends T) in // Holder<capture of ? extends T> // cannot be applied to (T) Tt= holder.get(); return t; } // 展示超类型通配 static <T> voidwildSupertype(Holder<? super T> holder, T arg) { // holder可以是持有任何T的基类型的容器,因此,set()可以接受T,因为任何可以工作于基类的对象都可以多态地作用于导出类(这里就是T) holder.set(arg); // T t = holder.get(); // Error: 由holder持有的类型可以是任何超类型,因此唯一安全的类型就是Object // 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 Object Longr4= 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) } }
publicclassChapter15_11_3 { publicstaticfinalintSIZE=10; publicstaticvoidmain(String[] args) { FixedSizeStack<String> strings = newFixedSizeStack<String>(SIZE); for(String s : "A B C D E F G H I J".split(" ")) strings.push(s); for(inti=0; i < SIZE; i++) { Strings= strings.pop(); System.out.print(s + " "); } }
@SuppressWarnings("unchecked") publicvoidf(String filepath)throws Exception{ // 下面演示由readObject()方法读取转型 ObjectInputStreamin=newObjectInputStream(newFileInputStream(filepath)); // 如果没有压制的注解,则会阐释警告 Unchecked cast from Object to List<Circle> // List<Circle> circles = (List<Circle>)in.readObject(); // 如果想继续使用泛型的情况下不产生警告,则可以使用Java EE5中的使用泛型类来转型 List<Circle> circles = List.class.cast(in.readObject()); // 但是你继续添加如下转型是仍会得到一个警告 // Type safety: Unchecked cast from List to List<Circle> circles = (List<Circle>)List.class.cast(in.readObject()); } } ```java ### 11.4、重载
由于擦除的原因,重载方法将产生相同的类型签名 ```java classUseList<W,T> { // 错误:Method f(List<T>) has the same erasure f(List<E>) as another method in type UseList<W,T> voidf(List<T> v) {} voidf(List<W> v) {} }
classComparablePetimplementsComparable<ComparablePet> { publicintcompareTo(ComparablePet arg) { return0; } } // 报错:The interface Comparable cannot be implemented more than once with different arguments: // Comparable<ComparablePet> and Comparable<TomCat> // 基类ComparablePet劫持了Comparable接口,只能进行ComparablePet的比较,而不能进行TomCat的比较 classTomCatextendsComparablePetimplementsComparable<TomCat>{ // Error: Comparable cannot be inherited with // different arguments: <Cat> and <Pet> publicintcompareTo(TomCat arg) { return0; } }
// To adapt a base type, you must use composition. // Make any Collection Addable using composition: // 创建一个Collection的Addable适配器 classAddableCollectionAdapter<T> implementsAddable<T> { private Collection<T> c; publicAddableCollectionAdapter(Collection<T> c) { this.c = c; } publicvoidadd(T item) { c.add(item); } }
// A Helper to capture the type automatically: classAdapter { publicstatic <T> Addable<T> collectionAdapter(Collection<T> c) { returnnewAddableCollectionAdapter<T>(c); } }
// To adapt a specific type, you can use inheritance. // Make a SimpleQueue Addable using inheritance: classAddableSimpleQueue<T> extendsSimpleQueue<T> implementsAddable<T> { publicvoidadd(T item) { super.add(item); } }
//Different types of function objects: // 运算法则:联合 interfaceCombiner<T> { T combine(T x, T y); } // 单参函数 interfaceUnaryFunction<R,T> { R function(T x); } // 收集器 interfaceCollector<T> extendsUnaryFunction<T,T> { T result(); // Extract result of collecting parameter } // interfaceUnaryPredicate<T> { booleantest(T x); }
classFunctional { // 结合seq中的所有对象 publicstatic <T> T reduce(Iterable<T> seq, Combiner<T> combiner) { Iterator<T> it = seq.iterator(); if(it.hasNext()) { Tresult= it.next(); while(it.hasNext()) result = combiner.combine(result, it.next()); return result; } // If seq is the empty list: returnnull; // Or throw exception } // Take a function object and call it on each object in // the list, ignoring the return value. The function // object may act as a collecting parameter, so it is // returned at the end. publicstatic <T> Collector<T> forEach(Iterable<T> seq, Collector<T> func) { for(T t : seq) func.function(t); return func; } // Creates a list of results by calling a // function object for each object in the list: publicstatic <R,T> List<R> transform(Iterable<T> seq, UnaryFunction<R,T> func) { List<R> result = newArrayList<R>(); for(T t : seq) result.add(func.function(t)); return result; } // Applies a unary predicate to each item in a sequence, // and returns a list of items that produced "true": publicstatic <T> List<T> filter(Iterable<T> seq, UnaryPredicate<T> pred) { List<T> result = newArrayList<T>(); for(T t : seq) if(pred.test(t)) result.add(t); return result; } // To use the above generic methods, we need to create // function objects to adapt to our particular needs: staticclassIntegerAdderimplementsCombiner<Integer> { public Integer combine(Integer x, Integer y) { return x + y; } } staticclassIntegerSubtracterimplementsCombiner<Integer> { public Integer combine(Integer x, Integer y) { return x - y; } } staticclassBigDecimalAdderimplementsCombiner<BigDecimal> { public BigDecimal combine(BigDecimal x, BigDecimal y) { return x.add(y); } } staticclassBigIntegerAdderimplementsCombiner<BigInteger> { public BigInteger combine(BigInteger x, BigInteger y) { return x.add(y); } } staticclassAtomicLongAdderimplementsCombiner<AtomicLong> { public AtomicLong combine(AtomicLong x, AtomicLong y) { // Not clear whether this is meaningful: returnnewAtomicLong(x.addAndGet(y.get())); } } // We can even make a UnaryFunction with an "ulp" // (Units in the last place): staticclassBigDecimalUlpimplementsUnaryFunction<BigDecimal,BigDecimal> { public BigDecimal function(BigDecimal x) { return x.ulp(); } } staticclassGreaterThan<T extendsComparable<T>> implementsUnaryPredicate<T> { private T bound; publicGreaterThan(T bound) { this.bound = bound; } publicbooleantest(T x) { return x.compareTo(bound) > 0; } } staticclassMultiplyingIntegerCollectorimplementsCollector<Integer> { privateIntegerval=1; public Integer function(Integer x) { val *= x; return val; } public Integer result() { return val; } } publicstaticvoidmain(String[] args) { // Generics, varargs & boxing working together: List<Integer> li = Arrays.asList(1, 2, 3, 4, 5, 6, 7); Integerresult= reduce(li, newIntegerAdder()); System.out.println(result);
result = reduce(li, newIntegerSubtracter()); System.out.println(result); System.out.println(filter(li, newGreaterThan<Integer>(4))); System.out.println(forEach(li, newMultiplyingIntegerCollector()).result()); System.out.println(forEach(filter(li, newGreaterThan<Integer>(4)), newMultiplyingIntegerCollector()).result()); MathContextmc=newMathContext(7); List<BigDecimal> lbd = Arrays.asList( newBigDecimal(1.1, mc), newBigDecimal(2.2, mc), newBigDecimal(3.3, mc), newBigDecimal(4.4, mc)); BigDecimalrbd= reduce(lbd, newBigDecimalAdder()); System.out.println(rbd); System.out.println(filter(lbd, newGreaterThan<BigDecimal>(newBigDecimal(3)))); // Use the prime-generation facility of BigInteger: List<BigInteger> lbi = newArrayList<BigInteger>(); BigIntegerbi= BigInteger.valueOf(11); for(inti=0; i < 11; i++) { lbi.add(bi); bi = bi.nextProbablePrime(); } System.out.println(lbi); BigIntegerrbi= reduce(lbi, newBigIntegerAdder()); System.out.println(rbi); // The sum of this list of primes is also prime: System.out.println(rbi.isProbablePrime(5)); List<AtomicLong> lal = Arrays.asList( newAtomicLong(11), newAtomicLong(47), newAtomicLong(74), newAtomicLong(133)); AtomicLongral= reduce(lal, newAtomicLongAdder()); System.out.println(ral); System.out.println(transform(lbd,newBigDecimalUlp())); } } /* Output: 28 -26 [5, 6, 7] 5040 210 11.000000 [3.300000, 4.400000] [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] 311 true 265 [0.000001, 0.000001, 0.000001, 0.000001] *///:~