资讯专栏INFORMATION COLUMN

(Thinking in Java)第15章 泛型

tinyq / 826人阅读

摘要:反省发放需要将泛型参数列表之余返回值之前杠杆利用类型参数推断现在可以了,别。现在可以显式的类型说明这段代码没毛病的,可变参数与泛型方法没啥好说用于的泛型方法方法可以透明的应用于实现了泛型接口的类。但是这个却可以指向各种是的对象。

二、简单泛型 2.一个堆栈类
package tij.generic;

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

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

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

3.RandomList
package tij.generic;

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

public class Test {
    public static void main(String[] args) {
        RandomList 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 {
    private ArrayList storage = new ArrayList();
    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 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, Iterable {
    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 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 {
        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  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 ls = New.list();
    }
}
class New {
    public static  List list() {
        return new ArrayList();
    }
}


现在可以了,别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 ls = New.list();
        f(New.list());
        m(New.map());
    }
    static void f(List x){
        
    }
    static void m(Map> m){
        
    }
}
class New {
    public static  List list() {
        return new ArrayList();
    }
    public static  Map map(){
        return new HashMap();
    }
}

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

2.可变参数与泛型方法

没啥好说

package tij.generic;

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

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

    public static  List makeList(T... args) {
        List result = new ArrayList();
        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 = Generators.fill(new ArrayList(),
                new CoffeeGenerator(), 4);
        for (Coffee c : coffee) {
            System.out.println(c);
        }
    }
}

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

}

interface Generator {
    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, Iterable {
    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 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 {
        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 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 implements Generator {
    private Class type;
    public BasicGenerator(Class type) {
        this.type = type;
    }
    public T next() {
        try {
            return type.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static  Generator create(Class type) {
        return new BasicGenerator(type);
    }
}

interface Generator {
    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 line = new LinkedList();
        Generators.fill(line, Customer.generator(), 15);

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

interface Generator {
    T next();
}

class Generators {
    public static  Collection fill(Collection coll, Generator 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 generator() {
        return new Generator() {
            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 generator = new Generator() {
        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 stringMaker = new ArrayMaker(String.class);
        String[] stringArray = stringMaker.create(9);
        System.out.println(Arrays.toString(stringArray));
    }
}

class ArrayMaker {
    private Class kind;
    ArrayMaker(Class 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[] gia;
    public static void main(String[] args) {
        gia = (Generic[]) new Object[SIZE];

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

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

    }
}

class Generic {}

class ArrayOfGeneric {

}
九、边界
package tij.generic;

import java.awt.Color;

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

interface HasColor {
    Color getColor();
}
class Colored {
    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 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 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 solid = new Solid2<>(new Bounded());
        solid.color();
        solid.getY();
        solid.weight();
    }
}

interface HasColor {
    Color getColor();
}

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

class Dimension {
    public int x, y, z;
}
class ColoredDimension2 extends Colored2 {
    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
        extends
            ColoredDimension2 {
    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 flist = new ArrayList();

这段代码会报错

List flist = new ArrayList();

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


如图,参数类型是null

1.编译期有多聪明

代码1:

package tij.generic;

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

public class Test {
    public static void main(String[] args) {
        List 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 = new Holder(new Apple());
        Apple d = Apple.get();
        Apple.set(d);
        Holder 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 {
    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 apples) {
        apples.add(new Apple());
        apples.add(new Jonathan());
        // apples.add(new Fruit());
    }
}

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


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

代码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  void writeExact(List list, T item) {
        list.add(item);
    }
    static List apples = new ArrayList();
    static List fruit = new ArrayList();
    static void f1() {
        writeExact(apples, new Apple());
        writeExact(fruit, new Apple());
        fruit.add(new Apple());
    }

    static  void writeWithWildcard(List 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 apples = Arrays.asList(new Apple());
    static List fruit = Arrays.asList(new Fruit());

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

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

        CovariantReader appleReader = new CovariantReader();
        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 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);
        T t=holder.get();
        return t;
    }
    static  void wildSupertype(Holder holder,T arg){
        holder.set(arg);
//        T t=holder.get();
        Object obj=holder.get();
    }
} 

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

4.类型转换
package tij.generic;

public class Test {
    static  void f1(Holder 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(1);
        f2(raw);
        f1(raw);
    }
}

class Holder {
    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{}
class Employee implements Payable{}
class Hourly extends Employee implements Payable{    
}
3、转型和警告
package tij.generic;

public class Test {
    public static final int SIZE = 10;
    public static void main(String[] args) {
        FixedSizeStack strings = new FixedSizeStack(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 {
    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{}
class CuriouslyRecurringGeneric extends GenericType{
    
}
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 element;
    void set(T arg) {
        element = arg;
    }
    T get() {
        return element;
    }
    void f() {
        System.out.println(element.getClass());
    }
}


class Other {}
class BasicOther extends BasicHolder {}
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 element;
    void set(T arg) {
        element = arg;
    }
    T get() {
        return element;
    }
    void f() {
        System.out.println(element.getClass());
    }
}

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

class A extends SelfBounded {}
class B extends SelfBounded {}
class C extends SelfBounded {
    C setAndGet(C arg) {
        set(arg);
        return get();
    }
}
class D {}
class E extends SelfBounded {}
class F extends SelfBounded {}
3.参数协变
class Base{}
class Derived extends Base{}
interface OrdinaryGetter{
    Base get();
}
interface DerivedGetter extends OrdinaryGetter{
    Derived get();
}

重写方法

interface GenericGetter> {
    T get();
}
interface Getter extends GenericGetter {}
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>{
    void set(T arg);
}

interface Setter extends SelfBoundSetter{}
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 = new ArrayList();
        oldStyleMethod(latte);

        List latte2 = Collections.checkedList(new ArrayList(),
                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 runner = new ProcessRunner();
        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 runner2 = new ProcessRunner();
        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 {
    void process(List resultCollector) throws E;
}
class ProcessRunner extends ArrayList> {
    List processAll() throws E {
        List resultCollector = new ArrayList();
        for (Processor processor : this) {
            processor.process(resultCollector);
        }
        return resultCollector;

    }
}

class Failure1 extends Exception {}
class Processor1 implements Processor {
    static int count = 3;
    @Override
    public void process(List 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 {
    static int count = 2;
    @Override
    public void process(List 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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67607.html

相关文章

  • Thinking in Java11 持有对象

    摘要:迭代器解决了这个问题。删除后于是我们可以写一个方法,接受一个类型,然后让他调用方法,这就不需要考虑这个是个还是了,也就是说,可以将遍历容器的操作与序列底层的结构分离,迭代器统一了对容器类的访问方式。十二和两种遍历的方法,与迭代器方法。 一、泛型和类型安全的容器 package tij.hoding; import java.util.ArrayList; public class ...

    v1 评论0 收藏0
  • Thinking in Java13 字符串

    摘要:四上的操作看五格式化输出运用和语言很相似和是等价的哟类格式化说明符转换六正则表达式网上教程学七扫描输入新增了类。 一、不可变String String类型的对象是不可变的,所有的改变实际上都是创建了一个新的String对象,另外当String作为传入参数的时候,其实实际上传入的是这个引用的一个拷贝,这个方法结束了之后这个传入的引用也就消失了,原来的那个String不会受到方法内的影响而...

    feng409 评论0 收藏0
  • Thinking in Java14 类型信息

    摘要:通过运行时类型信息,程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。编程应该尽量面向接口编程,应该对类型信息尽量的少了解二对象看书,书上写得好静态语句块在这个类被加载的时候运行。 一、为什么需要RTTI Run-Time Type Information。通过运行时类型信息,程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。编程应该尽量...

    tomorrowwu 评论0 收藏0
  • Thinking in Java10 内部类

    摘要:内部类中也可以取得这个外部类对象引用。创建成员内部类对象的时候需要外部类对象。另外在方法中的内部类不能加等权限修饰符,只能加和修饰符。可以在接口内部定义内部类,而且他们即使没有修饰,也会自动变成的。 Thinking in Java捞干货,写笔记 一、成员内部类 1.最基本使用 public class Demo { class Contents{ privat...

    Brenner 评论0 收藏0
  • 《On Java 8》中文版,又名《Java 编程思想》中文五版

    摘要:基于版本基于版本。由于中英行文差异,完全的逐字逐句翻译会很冗余啰嗦。译者在翻译中同时参考了谷歌百度有道翻译的译文以及编程思想第四版中文版的部分内容对其翻译死板,生造名词,语言精炼度差问题进行规避和改正。 来源:LingCoder/OnJava8 主译: LingCoder 参译: LortSir 校对:nickChenyx E-mail: 本书原作者为 [美] Bru...

    BingqiChen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<