java中优先考虑泛型----禁止数组类型的未受检转换和禁止标量类型(Effective java code)

Effective第26条中有提到优先考虑泛型,但是由于java会设计到数组所以会有泛型兼容数组的问题;首先泛型不应该与数组复用,但是java的历史原因,泛型的问世比较晚,必须兼容旧版本代码!所以有些情况必须拒绝受检!!!!

我们以stack为例:
在泛型没有问世之前是这样的:

public class Stack {  
    private Object[] elements;  
    private int size = 0;  
    private static final int DEFAULT_INITIAL_CAPACITY = 16;  

    public Stack() {  
        elements = new Object[DEFAULT_INITIAL_CAPACITY];  
    }  

    public void push(Object e) {  
        ensureCapacity();  
        elements[size++] = e;  
    }  

    public Object pop() {  
        if (size == 0)  
            throw new EmptyStackException();  
        E result = elements[--size];  
        elements[size] = null;  
        return result;  
    }  

    .......
}  

在java1.6之前,Object兼容其他类型,需要外部强转,泛型出现时,可以指定参数类型,并且在编译器受检;
所以Stack应该接收泛型类型的制定:

public class Stack<E> {  
    private E[] elements;  
    private int size = 0;  
    private static final int DEFAULT_INITIAL_CAPACITY = 16;  

    public Stack() {  
        elements = new E[DEFAULT_INITIAL_CAPACITY];  
    }  

    public void push(E e) {  
        ensureCapacity();  
        elements[size++] = e;  
    }  

    public E pop() {  
        if (size == 0)  
            throw new EmptyStackException();  
        E result = elements[--size];  
        elements[size] = null;  
        return result;  
    }  

 ....... 
}  

但是由于泛型就不可以具体实例化,所以下面这一句会抛出error:

 elements = new E[DEFAULT_INITIAL_CAPACITY]; 

在Effective java中提出两种方案,来解决这个问题:

1.方案一:禁止数组类型的未受检转换
  private Object[] elements;

  @SuppressWarnings("unchecked")
  public Stack() {  
        elements = new Object[DEFAULT_INITIAL_CAPACITY];  
    }  

 public void push(E e) {  
        ensureCapacity();  
        elements[size++] = e;  
    }  

    public E pop() {  
        if (size == 0)  
            throw new EmptyStackException();  
        E result = elements[--size];  
        elements[size] = null;  
        return result;  
    }  

我们把:
elements = new E[DEFAULT_INITIAL_CAPACITY] —>
elements = (E[])new Object[DEFAULT_INITIAL_CAPACITY]
这里用Object实例化数组,然后使用E[]进行强转,但是会抛出:

 warn:[unchecked] unchecked cast

数组类型未受检,所以我们禁止泛型受检 @SuppressWarnings(“unchecked”)

1.方案二:禁止标量类型
  public Stack() {  
        elements = new Object[DEFAULT_INITIAL_CAPACITY];  
    }  

     public void push(E e) {  
        ensureCapacity();  
        elements[size++] = e;  
    }  

    public E pop() {  
        if (size == 0)  
            throw new EmptyStackException();  
        @SuppressWarnings("unchecked")E result =
         (E)lements[--size];  
        elements[size] = null;  
        return result;  
    }  

方案二中数组就是一个Object的数组,但是在pop元素时候会对数组中的每一个标量进行E泛型的强转,然后进行类型转化,同第一种情况,在取元素时候会有类型未受检的warn,所以在元素的标量之前: @SuppressWarnings(“unchecked”)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值