二、简单泛型

2.一个堆栈类

package tij.generic;

public class Test {
    public static void main(String[] args) {
        LinkedStack<String> lss = new LinkedStack<String>();
        for (String s : "Phasers on stun".split(" "))
            lss.push(s);
        String s;
        while ((s = lss.pop()) != null) {
            System.out.println(s);
        }
    }
}

class LinkedStack<T> {
    private static class Node<U> {
        U item;
        Node<U> next;
        Node() {
            this.item = null;
            this.next = null;
        }
        Node(U item, Node<U> next) {
            this.item = item;
            this.next = next;
        }
        boolean end() {
            return item == null && next == null;
        }
    }
    private Node<T> top = new Node<T>();
    public void push(T item) {
        top = new Node<T>(item, top);
    }
    public T pop() {
        T result = top.item;
        if (!top.end())
            top = top.next;
        return result;
    }
}

在类名后面挂个<T>的意思就是,声明一下,我这个类里面要用到名字叫做T的泛型啦!

3.RandomList

package tij.generic;

import java.util.ArrayList;
import java.util.Random;

public class Test {
    public static void main(String[] args) {
        RandomList<String> rs = new RandomList<>();
        for (String s : "The quick brown fox jumped over the lazy brown dog"
                .split(" "))
            rs.add(s);
        for (int i = 0; i < 11; i++)
            System.out.print(rs.select() + " ");
    }
}

class RandomList<T> {
    private ArrayList<T> storage = new ArrayList<T>();
    private Random rand = new Random(47);
    public void add(T item) {
        storage.add(item);
    }
    public T select() {
        return storage.get(rand.nextInt(storage.size()));
    }
}

三、泛型接口

package tij.generic;

import java.util.Iterator;
import java.util.Random;

public class Test {
    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);
    }
}

interface Generator<T> {
    T next();
}
class Coffee {
    private static long counter = 0;
    private final long id = counter++;
    public String toString() {
        return getClass().getSimpleName() + " " + id;
    }
}

class Mocha extends Coffee {}
class Cappuccino extends Coffee {}
class Latte extends Coffee {}

class CoffeeGenerator implements Generator<Coffee>, Iterable<Coffee> {
    private Class<?>[] types = {Latte.class, Mocha.class, Latte.class};
    private static Random rand = new Random(47);
    public CoffeeGenerator() {

    }
    private int size = 0;
    public CoffeeGenerator(int sz) {
        this.size = sz;
    }
    @Override
    public Iterator<Coffee> iterator() {
        return new CoffeeIterator();
    }

    @Override
    public Coffee next() {
        try {
            return (Coffee) types[rand.nextInt(types.length)].newInstance();
        } 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();
        }
    }

}

四、泛型方法

对于static方法,无法访问泛型类的类型参数,所以如果static方法要使用泛型,这个方法就必须是泛型的。
反省发放需要将泛型参数列表之余返回值之前

package tij.generic;

public class Test {
    public <T> void f(T x){
        System.out.println(x.getClass().getName());
    }
    public static void main(String[] args) {
        Test t=new Test();
        t.f("x");
        t.f(1);
    }
}

1.杠杆利用类型参数推断

package tij.generic;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> ls = New.list();
    }
}
class New {
    public static <T> List<T> list() {
        return new ArrayList<T>();
    }
}

clipboard.png
现在可以了,别BB。
现在可以显式的类型说明

package tij.generic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        List<String> ls = New.list();
        f(New.<String>list());
        m(New.map());
    }
    static void f(List<String> x){
        
    }
    static void m(Map<String ,List<? extends New>> m){
        
    }
}
class New {
    public static <T> List<T> list() {
        return new ArrayList<T>();
    }
    public static <K,V> Map<K,V> map(){
        return new HashMap<K,V>();
    }
}

这段代码没毛病的,JDK1.8

2.可变参数与泛型方法

没啥好说

package tij.generic;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> ls = makeList("A");
        System.out.println(ls);
        ls = makeList("A", "B");
        System.out.println(ls);
    }

    public static <T> List<T> makeList(T... args) {
        List<T> result = new ArrayList<T>();
        for (T item : args)
            result.add(item);
        return result;
    }
}

3.用于Generator的泛型方法

package tij.generic;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Random;

public class Test {
    public static void main(String[] args) {
        Collection<Coffee> coffee = Generators.fill(new ArrayList<Coffee>(),
                new CoffeeGenerator(), 4);
        for (Coffee c : coffee) {
            System.out.println(c);
        }
    }
}

class Generators {
    public static <T> Collection<T> fill(Collection<T> coll, Generator<T> gen,
            int n) {
        for (int i = 0; i < n; i++)
            coll.add(gen.next());
        return coll;
    }

}

interface Generator<T> {
    T next();
}
class Coffee {
    private static long counter = 0;
    private final long id = counter++;
    public String toString() {
        return getClass().getSimpleName() + " " + id;
    }
}

class Mocha extends Coffee {}
class Cappuccino extends Coffee {}
class Latte extends Coffee {}

class CoffeeGenerator implements Generator<Coffee>, Iterable<Coffee> {
    private Class<?>[] types = {Latte.class, Mocha.class, Latte.class};
    private static Random rand = new Random(47);
    public CoffeeGenerator() {

    }
    private int size = 0;
    public CoffeeGenerator(int sz) {
        this.size = sz;
    }
    @Override
    public Iterator<Coffee> iterator() {
        return new CoffeeIterator();
    }

    @Override
    public Coffee next() {
        try {
            return (Coffee) types[rand.nextInt(types.length)].newInstance();
        } 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();
        }
    }

}

fill方法可以透明的应用于实现了泛型接口的类。

4.一个通用的Generator

package tij.generic;

public class Test {
    public static void main(String[] args) {
        Generator<CountedObject> gen = BasicGenerator
                .create(CountedObject.class);
        for (int i = 0; i < 5; i++) {
            System.out.println(gen.next());
        }
    }
}

class CountedObject {
    private static long counter = 0;
    private final long id = counter++;
    public long id() {
        return id;
    }
    public String toString() {
        return "CountedObject " + id;
    }
}

class BasicGenerator<T> implements Generator<T> {
    private Class<T> type;
    public BasicGenerator(Class<T> type) {
        this.type = type;
    }
    public T next() {
        try {
            return type.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static <T> Generator<T> create(Class<T> type) {
        return new BasicGenerator<T>(type);
    }
}

interface Generator<T> {
    T next();
}

我认为没什么意义

6.一个Set的实用工具

没什么卵用

五、匿名内部类与泛型

package tij.generic;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;

public class Test {
    static void serve(Teller t, Customer c) {
        System.out.println(t + " serves " + c);
    }
    public static void main(String[] args) {
        Random rand = new Random(47);
        Queue<Customer> line = new LinkedList<Customer>();
        Generators.fill(line, Customer.generator(), 15);

        List<Teller> tellers = new ArrayList<Teller>();
        Generators.fill(tellers, Teller.generator, 4);
        for (Customer c : line) {
            serve(tellers.get(rand.nextInt(tellers.size())), c);
        }
    }
}

interface Generator<T> {
    T next();
}

class Generators {
    public static <T> Collection<T> fill(Collection<T> coll, Generator<T> gen,
            int n) {
        for (int i = 0; i < n; i++)
            coll.add(gen.next());
        return coll;
    }

}

class Customer {
    private static long counter = 1;
    private final long id = counter++;
    private Customer() {

    }
    public String toString() {
        return "Customer" + id;
    }

    public static Generator<Customer> generator() {
        return new Generator<Customer>() {
            public Customer next() {
                return new Customer();
            }
        };
    }
}

class Teller {
    private static long counter = 1;
    private final long id = counter++;
    private Teller() {

    }
    public String toString() {
        return "Teller " + id;
    }
    public static Generator<Teller> generator = new Generator<Teller>() {
        public Teller next() {
            return new Teller();
        }
    };
}

六、构建复杂模型

什么gui东西

七、擦除的神秘之处

自己看书吧

4.边界的动作

package tij.generic;

import java.lang.reflect.Array;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        ArrayMaker<String> stringMaker = new ArrayMaker<String>(String.class);
        String[] stringArray = stringMaker.create(9);
        System.out.println(Arrays.toString(stringArray));
    }
}

class ArrayMaker<T> {
    private Class<T> kind;
    ArrayMaker(Class<T> kind) {
        this.kind = kind;
    }
    T[] create(int size) {
        return (T[]) Array.newInstance(kind, size);
    }
}

八、擦除的补偿

2.泛型数组

package tij.generic;

public class Test {
    static final int SIZE = 100;
    static Generic<Integer>[] gia;
    public static void main(String[] args) {
        gia = (Generic<Integer>[]) new Object[SIZE];

        gia = (Generic<Integer>[]) new Generic[SIZE];
        System.out.println(gia.getClass());
        gia[0] = new Generic<Integer>();

        // gia[1]=new Object();

    }
}

class Generic<T> {}

class ArrayOfGeneric {

}

九、边界

package tij.generic;

import java.awt.Color;

public class Test {
    public static void main(String[] args) {
        Solid<Bounded> solid = new Solid<>(new Bounded());
        solid.color();
        solid.getY();
        solid.weight();
    }
}

interface HasColor {
    Color getColor();
}
class Colored<T extends HasColor> {
    T item;
    Colored(T item) {
        this.item = item;
    }
    T getItem() {
        return item;
    }
    Color color() {
        return item.getColor();
    }
}

class Dimension {
    public int x, y, z;
}
class ColoredDimension<T extends Dimension & HasColor> {
    T item;
    ColoredDimension(T item) {
        this.item = item;
    }
    T getItem() {
        return item;
    }
    Color color() {
        return item.getColor();
    }
    int getX() {
        return item.x;
    }
    int getY() {
        return item.y;
    }
    int getZ() {
        return item.z;
    }

}

interface Weight {
    int weight();
}
class Solid<T extends Dimension & HasColor & Weight> {
    T item;
    Solid(T item) {
        this.item = item;
    }
    T getItem() {
        return item;
    }
    Color color() {
        return item.getColor();
    }
    int getX() {
        return item.x;
    }
    int getY() {
        return item.y;
    }
    int getZ() {
        return item.z;
    }
    int weight() {
        return item.weight();
    }
}

class Bounded extends Dimension implements HasColor, Weight {
    public Color getColor() {
        return null;
    }
    public int weight() {
        return 0;
    }
}

通过上述代码我可以知道,通过对反省进行集成的限定,可以限制泛型的类型
接下来可以看到如何在继承的每个层次上添加边界限制:

package tij.generic;

import java.awt.Color;

public class Test {
    public static void main(String[] args) {
        Solid2<Bounded> solid = new Solid2<>(new Bounded());
        solid.color();
        solid.getY();
        solid.weight();
    }
}

interface HasColor {
    Color getColor();
}

class HoldItem<T> {
    T item;
    HoldItem(T item) {
        this.item = item;
    }
    T getItem() {
        return item;
    }
}
class Colored2<T extends HasColor> extends HoldItem<T> {
    Colored2(T item) {
        super(item);
    }
    Color color() {
        return item.getColor();
    }
}

class Dimension {
    public int x, y, z;
}
class ColoredDimension2<T extends Dimension & HasColor> extends Colored2<T> {
    ColoredDimension2(T item) {
        super(item);
    }
    T getItem() {
        return item;
    }
    Color color() {
        return item.getColor();
    }
    int getX() {
        return item.x;
    }
    int getY() {
        return item.y;
    }
    int getZ() {
        return item.z;
    }

}

interface Weight {
    int weight();
}
class Solid2<T extends Dimension & HasColor & Weight>
        extends
            ColoredDimension2<T> {
    Solid2(T item) {
        super(item);
    }
    int weight() {
        return item.weight();
    }
}

class Bounded extends Dimension implements HasColor, Weight {
    public Color getColor() {
        return null;
    }
    public int weight() {
        return 0;
    }
}

通过上面两段代码可以知道,在继承的过程中,在每个层次上的类型参数都被添加了一定的边界进行限制。

十、通配符

通配符就是泛型里面的问号,结合eclipse的提示看一下参数类型会对理解这节有很大帮助

package tij.generic;

public class Test {
    public static void main(String[] args) {
        Fruit[] fruit=new Apple[10];
        fruit[0]=new Apple();
        fruit[1]=new Jonathan();
        try{
            fruit[0]=new Fruit();
        }catch(Exception e){
            System.out.println(e);
        }
        try{
            fruit[0]=new Orange();
        }catch(Exception e){
            System.out.println(e);
        }
        
    }
}

class Fruit{}
class Apple extends Fruit{}
class Jonathan extends Fruit{}
class Orange extends Fruit{}

通过以上代码可以知道,明明是一个apple数组,在接收jonathan对象的时候,编译器并没有报错,而在运行的时候才会报错,通过泛型,可以将这个错误转化为编译期的错误

List<Fruit> flist = new ArrayList<Apple>();

这段代码会报错

List<? extends Fruit> flist = new ArrayList<Apple>();

这段代码不仅不会报错,而且没办法往里传递任何信息。但是这个flist却可以指向各种是fruit的ArrayLIst对象。
因为编译器并不知道你到底想要啥

clipboard.png

clipboard.png
如图,参数类型是null

1.编译期有多聪明

代码1:

package tij.generic;

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<? extends Fruit> flist = Arrays.asList(new Apple());
        Apple a = (Apple) flist.get(0);
        flist.contains(new Apple());
        flist.indexOf(new Apple());
    }
}

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Fruit {}
class Orange extends Fruit {}

代码2:

package tij.generic;

import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        Holder<Apple> Apple = new Holder<Apple>(new Apple());
        Apple d = Apple.get();
        Apple.set(d);
        Holder<? extends Fruit> fruit = Apple;
        Fruit p = fruit.get();
        d = (Apple) fruit.get();
        // fruit.set(new Apple());
        fruit.setOb(new Apple());
        System.out.println(fruit.equals(d));
    }
}

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Fruit {}
class Orange extends Fruit {}

class Holder<T> {
    private T value;
    public Holder() {}
    public Holder(T val) {
        value = val;
    }
    public void set(T val) {
        value = val;
    }
    public void setOb(Object obj) {
        this.value = (T) obj;
    }
    public T get() {
        return value;
    }
    public boolean equals(Object obj) {
        return value.equals(obj);
    }
}

2.逆变

代码1:

package tij.generic;

import java.util.List;

public class Test {
    public static void main(String[] args) {}
}

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}

class SuperTypeWildcards {
    static void writerTo(List<? super Apple> apples) {
        apples.add(new Apple());
        apples.add(new Jonathan());
        // apples.add(new Fruit());
    }
}

? super Apple的意思就是,只要是Apple或者Apple的爹的意思,但事实上,正如上面所说,编译器并不知道你这个通配符代表的是什么,

clipboard.png
但是在super这里,至少所有的apple和apple的子类,全都是apple,这没错的。

clipboard.png

代码3:

package tij.generic;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        GenericWriting.f1();
        GenericWriting.f2();
    }
}

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}

class GenericWriting {
    static <T> void writeExact(List<T> list, T item) {
        list.add(item);
    }
    static List<Apple> apples = new ArrayList<Apple>();
    static List<Fruit> fruit = new ArrayList<Fruit>();
    static void f1() {
        writeExact(apples, new Apple());
        writeExact(fruit, new Apple());
        fruit.add(new Apple());
    }

    static <T> void writeWithWildcard(List<? super T> list, T item) {
        list.add(item);
    }
    static void f2() {
        writeWithWildcard(apples, new Apple());
        writeWithWildcard(fruit, new Apple());
    }
}

其实是可以的,书上说不可以

代码3:

package tij.generic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        GenericWriting.f1();
        GenericWriting.f2();
        GenericWriting.f3();
    }
}

class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}

class GenericWriting {

    static List<Apple> apples = Arrays.asList(new Apple());
    static List<Fruit> fruit = Arrays.asList(new Fruit());

    static <T> T readExact(List<T> list) {
        return list.get(0);
    }
    static void f1() {
        Apple a = readExact(apples);
        Fruit f = readExact(fruit);
        f = readExact(apples);
    }

    static class Reader<T> {
        T readExact(List<T> list) {
            return list.get(0);
        }
    }
    static void f2() {
        Reader<Fruit> fruitReader = new Reader<Fruit>();
        Fruit f = fruitReader.readExact(apples);// error
    }
    static class CovariantReader<T> {
        T readCovariant(List<? extends T> list) {
            return list.get(0);
        }
    }
    static void f3() {
        CovariantReader<Fruit> fruitReader = new CovariantReader<Fruit>();
        Fruit f = fruitReader.readCovariant(fruit);
        Fruit a = fruitReader.readCovariant(apples);

        CovariantReader<Apple> appleReader = new CovariantReader<Apple>();
        Apple ap = appleReader.readCovariant(apples);
    }
}

这是一次对比

3.无界通配符

class Wildcards{
    static void rawArgs(Holder holder,Object arg){
        holder.set(arg);
        holder.set(new Wildcards());
//        T t=holder.get();
//        Error
        Object obj=holder.get();
    }
    
    static void unboundedArg(Holder<?> holder,Object arg){
//        holder.set(arg);
//        holder.set(new Wildcards());
//        Error
        Object obj=holder.get();
    }
    
    static <T> T exact1(Holder<T> holder){
        T t=holder.get();
        return t;
    }
    static <T> T exact2(Holder<T> holder,T arg){
        holder.set(arg);
        T t=holder.get();
        return t;
    }
    static <T> T wildSubtype(Holder<? extends T> holder,T arg){
//        holder.set(arg);
        T t=holder.get();
        return t;
    }
    static <T> void wildSupertype(Holder<? super T> holder,T arg){
        holder.set(arg);
//        T t=holder.get();
        Object obj=holder.get();
    }
} 

破事儿真多,这玩意记不过来,边用边记吧,
书上看看得了

4.类型转换

package tij.generic;

public class Test {
    static <T> void f1(Holder<T> holder) {
        T t = holder.get();
        System.out.println(t.getClass());
    }
    static void f2(Holder<?> holder) {
        f1(holder);

    }
    public static void main(String[] args) {
        Holder raw = new Holder<Integer>(1);
        f2(raw);
        f1(raw);
    }
}

class Holder<T> {
    private T value;
    public Holder() {}
    public Holder(T val) {
        value = val;
    }
    public void set(T val) {
        value = val;
    }
    public T get() {
        return value;
    }
    public boolean equals(Object obj) {
        return value.equals(obj);
    }
}

十一、问题

1.任何基本类型都不能作为类型参数

2.实现参数化接口

interface Payable<T>{}
class Employee implements Payable<Employee>{}
class Hourly extends Employee implements Payable<Hourly>{    
}

3、转型和警告

package tij.generic;

public class Test {
    public static final int SIZE = 10;
    public static void main(String[] args) {
        FixedSizeStack<String> strings = new FixedSizeStack<String>(SIZE);
        for (String s : "A B C D E F G H I J".split(" "))
            strings.push(s);
        for (int i = 0; i < SIZE; i++) {
            String s = strings.pop();
            System.out.print(s + " ");
        }
    }
}

class FixedSizeStack<T> {
    private int index = 0;
    private Object[] storage;
    public FixedSizeStack(int size) {
        storage = new Object[size];
    }
    public void push(T item) {
        storage[index++] = item;
    }
    public T pop() {
        return (T) storage[--index];
    }
}

4.重载

5.基类劫持了接口

十二、自限定的类型

1.古怪的循环泛型

class GenericType<T>{}
class CuriouslyRecurringGeneric extends GenericType<CuriouslyRecurringGeneric>{
    
}

2.自限定

package tij.generic;

public class Test {
    public static void main(String[] args) {
        BasicOther b = new BasicOther();
        BasicOther b2 = new BasicOther();
        b.set(new Other());
        Other other = b.get();
        b.f();
    }
}

class BasicHolder<T> {
    T element;
    void set(T arg) {
        element = arg;
    }
    T get() {
        return element;
    }
    void f() {
        System.out.println(element.getClass());
    }
}


class Other {}
class BasicOther extends BasicHolder<Other> {}
package tij.generic;

public class Test {
    public static void main(String[] args) {
        A a = new A();
        a.set(new A());
        a = a.set(new A()).get();
        a = a.get();
        B b = new B();
        b.set(a);
        a = b.get();
        C c = new C();
        c = c.setAndGet(new C());

    }
}

class BasicHolder<T> {
    T element;
    void set(T arg) {
        element = arg;
    }
    T get() {
        return element;
    }
    void f() {
        System.out.println(element.getClass());
    }
}

class SelfBounded<T extends SelfBounded<T>> {
    T element;
    SelfBounded<T> set(T arg) {
        this.element = arg;
        return this;
    }
    T get() {
        return element;
    }
}

class A extends SelfBounded<A> {}
class B extends SelfBounded<A> {}
class C extends SelfBounded<C> {
    C setAndGet(C arg) {
        set(arg);
        return get();
    }
}
class D {}
class E extends SelfBounded<D> {}
class F extends SelfBounded {}

3.参数协变

class Base{}
class Derived extends Base{}
interface OrdinaryGetter{
    Base get();
}
interface DerivedGetter extends OrdinaryGetter{
    Derived get();
}

重写方法

interface GenericGetter<T extends GenericGetter<T>> {
    T get();
}
interface Getter extends GenericGetter<Getter> {}
class GenericsAndReturnTypes {
    void test(Getter g) {
        Getter result = g.get();
        GenericGetter gg = g.get();
    }
}

自限定泛型

class OrdinarySetter{
    void set(Base base){
        System.out.println("OrdinarySetter.set(Base)");
    }
}
class DerivedSetter extends OrdinarySetter{
    void set(Derived derived){
        System.out.println("DerivedSetter.set(Derived)");
    }
}

这是重载,不是重写

interface SelfBoundSetter<T extends SelfBoundSetter<T>>{
    void set(T arg);
}

interface Setter extends SelfBoundSetter<Setter>{}
class SelfBoundingAndCovariantArguments{
    void testA(Setter s1,Setter s2,SelfBoundSetter sbs){
        s1.set(s2);
        s1.set(sbs);
    }
}

十三、动态类型安全

package tij.generic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    @SuppressWarnings("unchecked")
    static void oldStyleMethod(List probablyLatte) {
        probablyLatte.add(new Cappuccino());
    }
    public static void main(String[] args) {
        List<Latte> latte = new ArrayList<Latte>();
        oldStyleMethod(latte);

        List<Latte> latte2 = Collections.checkedList(new ArrayList<Latte>(),
                Latte.class);
        oldStyleMethod(latte2);

    }
}

class Coffee {}
class Latte extends Coffee {}
class Cappuccino extends Coffee {}

十四、异常

package tij.generic;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        ProcessRunner<String, Failure1> runner = new ProcessRunner<String, Failure1>();
        for (int i = 0; i < 3; i++)
            runner.add(new Processor1());

        try {
            runner.processAll();
        } catch (Failure1 e) {
            // TODO Auto-generated catch block
            System.out.println(e);
        }

        ProcessRunner<Integer, Failure2> runner2 = new ProcessRunner<Integer, Failure2>();
        for (int i = 0; i < 3; i++)
            runner2.add(new Processor2());

        try {
            runner2.processAll();
        } catch (Failure2 e) {
            // TODO Auto-generated catch block
            System.out.println(e);
        }
    }
}

interface Processor<T, E extends Exception> {
    void process(List<T> resultCollector) throws E;
}
class ProcessRunner<T, E extends Exception> extends ArrayList<Processor<T, E>> {
    List<T> processAll() throws E {
        List<T> resultCollector = new ArrayList<T>();
        for (Processor<T, E> processor : this) {
            processor.process(resultCollector);
        }
        return resultCollector;

    }
}

class Failure1 extends Exception {}
class Processor1 implements Processor<String, Failure1> {
    static int count = 3;
    @Override
    public void process(List<String> resultCollector) throws Failure1 {
        if (count-- > 1)
            resultCollector.add("Hep!");
        else
            resultCollector.add("Ho!");
        System.out.println(resultCollector);
        if (count < 0) {
            throw new Failure1();
        }

    }
}

class Failure2 extends Exception {}
class Processor2 implements Processor<Integer, Failure2> {
    static int count = 2;
    @Override
    public void process(List<Integer> resultCollector) throws Failure2 {
        if (count-- == 0)
            resultCollector.add(47);
        else
            resultCollector.add(11);
        System.out.println(resultCollector);
        if (count < 0)
            throw new Failure2();
    }

}

说实话,这有什么卵意义么

十五、混型

2.与接口混合

package tij.generic;

import java.util.Date;

public class Test {
    public static void main(String[] args) {
        Mixin mixin1 = new Mixin(), mixin2 = new Mixin();
        mixin1.set("test string 1");
        mixin2.set("test string 2");
        System.out.println(mixin1.get() + " " + mixin1.getStamp() + " "
                + mixin1.getSerialNumber());
        System.out.println(mixin2.get() + " " + mixin2.getStamp() + " "
                + mixin2.getSerialNumber());
    }
}

interface TimeStamped {
    long getStamp();
}
class TimeStampedImp implements TimeStamped {
    private final long timeStamp;
    public TimeStampedImp() {
        super();
        this.timeStamp = new Date().getTime();
    }
    public long getStamp() {
        return this.timeStamp;
    }
}

interface SerialNumbered {
    long getSerialNumber();
}

class SerialNumberedImp implements SerialNumbered {
    private static long counter = 1;
    private final long serialNumber = counter++;
    public long getSerialNumber() {
        return serialNumber;
    }
}

interface Basic {
    void set(String val);
    String get();
}

class BasicImp implements Basic {
    private String value;
    public void set(String val) {
        value = val;
    }
    public String get() {
        return value;
    }
}

class Mixin extends BasicImp implements TimeStamped, SerialNumbered {
    private TimeStamped timeStamp = new TimeStampedImp();
    private SerialNumbered serialNumber = new SerialNumberedImp();
    @Override
    public long getSerialNumber() {
        return serialNumber.getSerialNumber();
    }

    @Override
    public long getStamp() {
        return timeStamp.getStamp();
    }

}

3.使用装饰器模式

package tij.generic;

import java.util.Date;

public class Test {
    public static void main(String[] args) {
        TimeStamped t = new TimeStamped(new Basic());
        TimeStamped t2 = new TimeStamped(new SerialNumbered(new Basic()));
        
        
        SerialNumbered s = new SerialNumbered(new Basic());
        SerialNumbered s2 = new SerialNumbered(new TimeStamped(new Basic()));
    }
}

class Basic {
    private String value;
    void set(String val) {
        this.value = val;
    };
    String get() {
        return value;
    };
}

class Decorator extends Basic {
    protected Basic basic;
    public Decorator(Basic basic) {
        this.basic = basic;
    }
    public void set(String val) {
        basic.set(val);
    }
    public String get() {
        return basic.get();
    }
}

class TimeStamped extends Decorator {
    private final long timeStamp;
    public TimeStamped(Basic basic) {
        super(basic);
        this.timeStamp = new Date().getTime();
    }
    public long getStamp() {
        return this.timeStamp;
    }
}

class SerialNumbered extends Decorator {
    public SerialNumbered(Basic basic) {
        super(basic);
    }
    private static long counter = 1;
    private final long serialNumber = counter++;
    public long getSerialNumber() {
        return serialNumber;
    }
}

十六、潜在类型机制

之后pass不看了,费劲

end


z_dominic
115 声望15 粉丝

你有freestyle吗?