第二十六条:优先考虑泛型

一、利用Object写的堆栈实例

public class CommonStack {
	private static final int DEFAULT_SIZE = 16;
	//用来存储的数组
	private Object[] objects = new Object[DEFAULT_SIZE];
	//当前存储的位置
	private int count = 0;
	
	public void put(Object obj){
		//首先判断是否数组满了,如果满了扩充数组
		expandArray();
		objects[count] = obj;
		++count;
	}

	private void expandArray(){
		if(count == objects.length){
			//扩充容量
			objects = Arrays.copyOf(objects, 2*count);
		}
	}
	
	public Object pop(){
		//首先判断是否数组为空
		if (!isEmpty()){
			Object obj = objects[count];
			--count;<pre name="code" class="java"><span>			</span>objects[count] = null;
return obj;}return null;}private boolean isEmpty(){if (count == 0){return true;}else {return false;}}}
 
 

二、将Object栈全部改为用泛型实现栈

public class GenericsStack<E> {
	private static final int DEFAULT_SIZE = 16;
	//该行出现了错误,无法创建泛型数组
	private E[] objects = new E[DEFAULT_SIZE];

	private int count = 0;
	
	public void put(E obj){
		expandArray();
		objects[count] = obj;
		++count;
	}

	private void expandArray(){
		if(count == objects.length){
			//扩充容量
			objects = Arrays.copyOf(objects, 2*count);
		}
	}
	
	public E pop(){
		//首先判断是否数组为空
		if (!isEmpty()){
			E obj = objects[count];
			--count;
<span style="white-space:pre">			</span>objects[count] = null;
			return obj;
		}
		return null;
		
	}

	
	private boolean isEmpty(){
		if (count == 0){
			return true;
		}
		else {
			return false;
		}
	}

}
解决方案
第一种:用泛型进行转型
@SuppressWarnings("unchecked")
private E[] objects = (E[])new Object[DEFAULT_SIZE];
第二种方法:将数据存出到Object数组中,然后在从Object数组中拿出来,再转型为E类型。
	private Object[] objects = new Object[DEFAULT_SIZE];

	public E pop(){
		//首先判断是否数组为空
		if (!isEmpty()){
			@SuppressWarnings("unchecked")
			E obj = (E)objects[count];
			--count;
			return obj;
		}
		return null;
		
	}
推荐使用第二种方法:原因,禁止数组的警告比禁止对象的强制转换的警告还要危险。

三、有限类型参数与无限类型参数

无限类型参数:泛型的参数类型能够接收任何值
public class GenericsStack<E> 就是无限类型参数。
所以可以 new GenericsStack<String>()、new GenericsStack<Number>();
有限类型参数:
public class GenericsStack<E extends Number> 就表示优先类型参数。
该类只能接收Number或者Number的子类。
所以 new GenericsStack<String>()是会报错的。

有限类型参数的原理及应用:
我们知道泛型会在编译期间擦除参数类型,但是擦除是有边界的。虚拟机会将类型参数擦除到其的边界。
比如说:
public class GenericsStack<E>这个类,我们知道所有的类都继承了Object这个类,所以虚拟机可以确定E这个类一定是Object的子类,那么虚拟机将会将其擦除到其边界,也就是Object类。
我们可以设定这个边界,告诉虚拟机,我输入的类型参数都是在这个边界内的。就可以这样
public class GenericsStack<E extends Number> 说明:输入的参数,都必须是Number的子类。那么虚拟机就会将该参数擦除到Number类。
那么这样的好处是什么呢?
①、限定可作为类型参数的类
②、既然都知道了其边界是Number,那么就表示调用Number类下的所有方法都是安全的。
就能这样:(额。。。这个例子不太好,因为是错误,但是原理是这样的)
public class LimitGenerics <E extends Number>{
	public void getData(E data){
		byte myBytes = data.byteValue();//可直接调用Number类下的方法
	}
}








	
	private boolean isEmpty(){

	
	private boolean isEmpty(){

	
	private boolean isEmpty(){
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值