Java泛型再学习

引用地址:http://www.blogjava.net/killme2008/archive/2007/06/05/122174.html

http://blog.csdn.net/fbysss/article/details/3979725


 泛型引入java语言已经有很长一段时间了,在JDK5出来的时候也非常认真地学习过,不过学习的资料都是网上泛滥并且重复的教程。这几天下了《The Java Programming Language》的第4版,准备把jdk5引入的新东西再重新系统地学习一次,同时再次回顾下java基础。今天记录下学习泛型那一章的注意点。
一、泛型类型的声明
1.需要着重注意的一点,比如声明类Cell<E>:

package net.rubyeye.javaprogramming.generic;

public class Cell<E> {
    private Cell<E> next;

    private E element;

    public Cell(E element) {
        this.element = element;
    }

    public Cell(E element, Cell<E> next) {
        this.next = next;
        this.element = element;
    }

    public E getElement() {
        return element;
    }

    public void setElement(E element) {
        this.element = element;
    }

    public Cell<E> getNext() {
        return next;
    }

    public void setNext(Cell<E> next) {
        this.next = next;
    }

}
然后如此使用:

Cell<String> strCell = new Cell<String>("Hello");
Cell<Integer> intCell = new Cell<Integer>(25);

那么Cell<String>和Cell<Integer>是两个类吗?不,他们是同一个类,通过下面的实验证明:

assertTrue(strCell.getClass() == intCell.getClass()));

java泛型的实现采用的“擦拭法”,Cell<E>仍然是一个类,无论E被任何具体的类型所替代。 

2 .泛型的类型参数不能用于static变量、static方法和static初始化,比如下面的使用方式都不能编译通过:

public class Cell<E> {
    private static Cell<E> next;
    
    private static void test(E e){
        
    }

同样,静态方法是与类相关联的,调用也只能通过类,假设Cell有一个静态方法test,怎么调用才是正确的呢?

Cell<E>.test();  //编译错误
Cell<String>.test();  //同样编译错误
Cell.test();  //正确的方式

3 .类型参数可以继承其他的类和接口,如果有多个接口可以用&符号连接,通过extend参数限制了类型参数的范围,比如:

interface SortedCharSeqCollection<E extends Comparable<E>
                                  & CharSequence> {
    //  sorted char sequence collection methods 
}

SortedCharSeqCollection的类型参数E强制继承自Comparable和CharSequence接口,也就是替代的具体的类型参数必须实现这两个接口,从而限制了类型参数(type parameter)。

4 .比较有趣的内部类的泛型,对于静态内部类的类型参数可以与外部类的类型参数名不一样,静态内部类的类型参数与外部类的类型参数其实没有一点关系,比如:

class SingleLinkQueue<E> {
    static class Cell<E> {
        private Cell<E> next;
        private E element;
        public Cell(E element) {
            this.element = element;
        }
        public Cell(E element, Cell<E> next) {
            this.element = element;
            this.next = next;
        }
        public E getElement() {
            return element;
        }
        /*  rest of Cell methods as before  */
    }

    protected Cell<E> head;
    protected Cell<E> tail;

    /*  rest of SingleLinkQueue methods as before  */
}

Cell<E>类的声明和SingleLinkQueue<E> 两个类中的E仅仅是名称相同,他们之间的关联是通过head和tail的声明才关联在一起,你可以将Cell<E>中的E改成F也没关系,比如:

package net.rubyeye.javaprogramming.generic;

class AnotherSingleLinkQueue<E> {
    static class Cell<F> {
        private Cell<F> next;

        private F element;

        public Cell(F element) {
            this.element = element;
        }

        public Cell(F element, Cell<F> next) {
            this.element = element;
            this.next = next;
        }

        public F getElement() {
            return element;
        }
        /*  rest of Cell methods as before  */
    }

    protected Cell<E> head;

    protected Cell<E> tail;

    /*  rest of SingleLinkQueue methods as before  */
}

而一般的内部类就不一样了,内部类可以直接使用外部类的类型参数甚至隐藏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值