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

本文介绍了Java中的泛型如何应用于匿名内部类,并探讨了类型擦除的概念及其影响。通过示例说明了匿名内部类如何在泛型上下文中工作,同时解释了在运行时泛型类型信息的丢失以及擦除对于兼容非泛型代码的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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<Customer> generator(){
        return new Generator<Customer>() {
            @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<Teller> generator = new Generator<Teller>() {       
        @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<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(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表达式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值