[Thinking in Java]15.泛型

来源:互联网 发布:lua for windows 5.2 编辑:程序博客网 时间:2024/04/28 22:29

1.泛型接口与工厂方法设计模式相结合.

public class CoffeeGeneratorimplements Generator<Coffee>, Iterable<Coffee> {  private Class[] types = { Latte.class, Mocha.class,    Cappuccino.class, Americano.class, Breve.class, };  private static Random rand = new Random(47);  public CoffeeGenerator() {}  // For iteration:  private int size = 0;  public CoffeeGenerator(int sz) { size = sz; }  public Coffee next() {    try {      return (Coffee)        types[rand.nextInt(types.length)].newInstance();      // Report programmer errors at run time:    } catch(Exception e) {      throw new RuntimeException(e);    }  }  class CoffeeIterator implements Iterator<Coffee> {    int count = size;    public boolean hasNext() { return count > 0; }    public Coffee next() {      count--;      return CoffeeGenerator.this.next();    }    public void remove() { // Not implemented      throw new UnsupportedOperationException();    }  };  public Iterator<Coffee> iterator() {    return new CoffeeIterator();  }  public static void main(String[] args) {    CoffeeGenerator gen = new CoffeeGenerator();    for(int i = 0; i < 5; i++)      System.out.println(gen.next());    for(Coffee c : new CoffeeGenerator(5))      System.out.println(c);  }}

2.与模板方法设计模式相结合.(模板方法设计模式我的理解是在接口与实现之间再加一个抽象类,完成基本实现)

abstract class GenericWithCreate<T> {  final T element;  GenericWithCreate() { element = create(); }  abstract T create();}class X {}class Creator extends GenericWithCreate<X> {  X create() { return new X(); }  void f() {    System.out.println(element.getClass().getSimpleName());  }}public class CreatorGeneric {  public static void main(String[] args) {    Creator c = new Creator();    c.f();  }}

3.装饰器设计模式.这一点似乎和泛型关系不大?(装饰器模式就是类的不同组合,实现一种复杂的功能,典型应用在java i/o)

4.与动态代理模式结合.

class MixinProxy implements InvocationHandler {  Map<String,Object> delegatesByMethod;  public MixinProxy(TwoTuple<Object,Class<?>>... pairs) {    delegatesByMethod = new HashMap<String,Object>();    for(TwoTuple<Object,Class<?>> pair : pairs) {      for(Method method : pair.second.getMethods()) {        String methodName = method.getName();        // The first interface in the map        // implements the method.        if (!delegatesByMethod.containsKey(methodName))          delegatesByMethod.put(methodName, pair.first);      }    }  }  public Object invoke(Object proxy, Method method,    Object[] args) throws Throwable {    String methodName = method.getName();    Object delegate = delegatesByMethod.get(methodName);    return method.invoke(delegate, args);  }  @SuppressWarnings("unchecked")  public static Object newInstance(TwoTuple... pairs) {    Class[] interfaces = new Class[pairs.length];    for(int i = 0; i < pairs.length; i++) {      interfaces[i] = (Class)pairs[i].second;    }    ClassLoader cl =      pairs[0].first.getClass().getClassLoader();    return Proxy.newProxyInstance(      cl, interfaces, new MixinProxy(pairs));  }}
5.泛型与数组:无法直接创建数组.有趣的是,你可以声明一个泛型数组,但是没有办法初始化.

6.推荐创建泛型数组的方式:

public class GenericArray2<T> {  private Object[] array;  public GenericArray2(int sz) {    array = new Object[sz];  }  public void put(int index, T item) {    array[index] = item;  }  @SuppressWarnings("unchecked")  public T get(int index) { return (T)array[index]; }  @SuppressWarnings("unchecked")  public T[] rep() {    return (T[])array; // Warning: unchecked cast  }  public static void main(String[] args) {    GenericArray2<Integer> gai =      new GenericArray2<Integer>(10);    for(int i = 0; i < 10; i ++)      gai.put(i, i);    for(int i = 0; i < 10; i ++)      System.out.print(gai.get(i) + " ");    System.out.println();    try {      Integer[] ia = gai.rep();    } catch(Exception e) { System.out.println(e); }  }}

7.通配符的使用原则:PECS producer-extends ,consumer-super.如果参数产生实例供函数使用,就是生产者,如果参数消费实例,则是消费者.不要用通配符类型作为返回类型.

例如我们将 public static <T extends Comparable<T> > max(List<T> list> 修改成如下:

public static<T extends Comparable<? super T> > max(List<? extends T> list )理由如下:

1)list是生产者,生成实例供max选择,因此需要? extends T.

2)Comparable是消费者(永远是消费者),需要两个实例来比较,因此改写成 Comparable<? super T>

0 0
原创粉丝点击