java编程思想读书笔记 第十五章 泛型 (匿名内部类和擦除)

1.匿名内部类
泛型还可以应用于内部类以及匿名内部类。下面的例子使用匿名内部类实现了Generator接口:

public 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() {
            @Override
            public Customer next() {
                return new Customer();
            }
        };
    }
}
public class Teller {
    private static long counter = 1;
    private final long id = counter++;
    private Teller(){}
    @Override
    public String toString() {
        return "Teller" + id;
    }
    public static Generator generator = new Generator() {       
        @Override
        public Teller next() {
            return new Teller();
        }
    };

}
public class BankTeller {
    public static void serve(Teller t,Customer c){
        System.out.println(t + "serve" + c);
    }
    public static void main(String[] args) {
        Random random = 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(random.nextInt(tellers.size())), c);
        }
    }
}
output:
Teller3serveCustomer1
Teller2serveCustomer2
Teller3serveCustomer3
Teller1serveCustomer4
Teller1serveCustomer5
Teller3serveCustomer6
Teller1serveCustomer7
Teller2serveCustomer8
Teller3serveCustomer9
Teller3serveCustomer10
Teller2serveCustomer11
Teller4serveCustomer12
Teller2serveCustomer13
Teller1serveCustomer14
Teller1serveCustomer15

Customer和Teller类都只有private的构造器,这可以强制你必须使用Generator对象(这里的Generator接口和Generators类都是前两篇博客出现的)。Customer有一个generator()方法,每次执行它都会生成一个新的Generator对象。由于Customer中的generator()方法,以及Teller中的Generator对象都声明成了static的,所以它们无法作为接口的一部分,因此无法用接口这种特定的惯用法来泛化这二者。尽管如此,它们在fill()方法中都工作得很好。

2.擦除的神秘之处
在泛型的代码内部,无法获得任何有关泛型参数类型的信息。因此,你可以知道诸如类型参数标识符和泛型类型边界这类的信息——你却无法知道用来创建某个特定实例的实际的类型参数。java泛型时使用擦除来实现的,这意味着当你再使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List 和List在运行时事实上是相同的类型。这两种形式都被擦除成它们的“原生”类型,即List。
擦除主要的正当理由是从非泛化代码到泛化代码的转变过程,以及在不破坏现有类库的情况下,将泛型融入java语音。擦除使得现有的非泛型客户端代码能够在不改变的情况下继续使用,直至客户端准备好用泛型重写这些代码。擦除的代价是显著的。泛型不能用于显式地引用运行时类型的操作之中,例如转型、instanceof和操作和new表达式。

你可能感兴趣的:(java编程思想读书笔记,java,泛型,匿名内部类,擦除)