黑马程序员:泛型介绍:JDK1.5新特性

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个安全机制

格式:通过<>来定义要操作的引用数据类型
集合<参数类型> ,该参数类型不可以用基本数据类型(int char等),只有用引用数据类型,如String,Integer,数组等
如:ArrayList<String> al = new ArrayList<String>();
Iterator<String> it = al.iterator();
好处:
1.将运行时期出现问题ClassCastException,转移到了编译时期,方便于程序员解决问题,让运行时期问题减少
2.避免了强制转换的麻烦

在使用Java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见
只要见到<>就要定义泛型 API中会有写明,比如ArrayList<E>
<>就是用来接收类型的
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可

示例:
import java.util.*;
class TreeSetStringTest
{
	public static void main(String[] args)
	{
		TreeSet<String> ts = new TreeSet<String>(new Comparator<String>(){
			public int compare(String str1, String str2) //因为Comparator接口支持泛型,所以覆盖可以这样写
			{
				if (!(str1 instanceof String) || !(str2 instanceof String))
					throw new RuntimeException("不是一个字符串");
				/*正序
				int num = new Integer(str1.length()).compareTo(str2.length());
				if (num==0)
					return str1.compareTo(str2);
				*/
				//倒序
				int num = new Integer(str2.length()).compareTo(str1.length());
				if (num==0)
					return str2.compareTo(str1);
				return num;
			}
		});
		
		ts.add("a");
		ts.add("abc");
		ts.add("bb");
		ts.add("aa");
		//ts.add(4); //4自动装箱为new Integer(4); 因为定义了泛型<String>,这个是整型,所以编译时就会出现错
		for (Iterator<String> it = ts.iterator(); it.hasNext(); ) //因为Iterator定义了泛型<String>
		{
			String s = it.next(); //所以这里不用强制转换
			sop(s);
		}
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

泛型类
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展(强转),现在可以定义泛型来完成扩展
示例:
class Tools<E>
{
	private E e;
	public void setObject(E e)
	{
		this.e = e;
	}
	public E getObject()
	{
		return e;
	}
}

泛型定义在类上
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么该方法传入的类型已经被类中定义的类型固定了,除非重新创建新类型的类 即 Tools<String> t1 = new Tools<String>(); Tools<Integer> t2 = new Tools<Integer>();

泛型定义在方法上
为了让不同方法可以操作不同类型,而且类型不确定的情况下,可以将泛型定义在方法上
注意:静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上
原因:静态先加载对象后加载,而泛型类上的参数要等对象建立之后才知道该参数的值是什么,即静态不能访问非静态

泛型定义在接口上
示例
interface Inter<E>
{
	void show(E e);
}
class Tools<E> implements Inter<E>
{
	public void show(E e)
	{
		System.out.println("show:"+e);
	}
	public <Q> void print(Q q)
	{
		System.out.println("print:"+q);	
	}
	public static <Q> void get(Q q) //此Q和print方法中的Q无关
	{
		System.out.println("get:"+q);
	} 
}
class NewDemo
{
	public static void main(String[] args)
	{
		Tools<String> tl = new Tools<String>();
		tl.show("abc");
		//tl.show(4); Tools类泛型定义的数据类型为String,所以编译出错
		tl.print("cde");
		tl.print(5);
		tl.get(3.5);
	}
	
}

泛型限定
? 通配符,也叫占位符
<? extends Fu> 上限:接收Fu类或Fu类的子类
<? super Zi> 下限:接收Zi类或者Zi类的父类,注意super最上层为Object
注:若使用泛型限制取值,使用方法时,该泛型范围内,都应该具备该方法,否则编译不通过


示例:
import java.util.*;
class Fu
{
	private String name;
	Fu(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return name;
	}
}
class Zi extends Fu
{
	Zi(String name)
	{
		super(name);
	}


}
class Other
{
	private String name;
	Other(String name)
	{
		this.name = name;
	}
}
class NewDemo
{
	public static void main(String[] args)
	{
		ArrayList<Fu> al = new ArrayList<Fu>();
		al.add(new Zi("Fu-Zi1")); //父类容器可以存放子类元素,但不能ArrayList<Fu> al = new ArrayList<Zi>();
		al.add(new Zi("Fu-Zi2"));
		al.add(new Fu("Fu-1"));
		al.add(new Fu("Fu-2"));
		
		ArrayList<Zi> az = new ArrayList<Zi>();
		az.add(new Zi("az-1"));
		az.add(new Zi("az-2"));
		az.add(new Zi("az-3"));
		
		ArrayList<Other> ot = new ArrayList<Other>();
		ot.add(new Other("ot-1"));
		ot.add(new Other("ot-2"));
		ot.add(new Other("ot-3"));
		
		getListDown(al);
		getListAny(ot);
		getListT(ot);
	}
	public static void getListDown(ArrayList<? extends Fu> al)  //ArrayList泛型只要是Fu类或者Fu类的子类即可传入,即al,az可以传入,ot不可以传入
	{
		for (Iterator<? extends Fu> it = al.iterator(); it.hasNext(); )
		{
			System.out.println(it.next().getName()); //因为泛型限制中的Fu,Zi里都有这个方法,所以可以使用
		}
	}
	public static void getListUp(ArrayList<? super Zi> al)  //ArrayList泛型只要是Fu类或者Fu类的子类即可传入,即al,az可以传入,ot不可以传入
	{
		for (Iterator<? super Zi> it = al.iterator(); it.hasNext(); )
		{
			System.out.println(it.next()); //因为super的最上级是Object,Object中并无getName(),所以无法使用自定义的getName()方法
		}
	}
	public static void getListAny(ArrayList<?> al)  //ArrayList泛型随便是什么类型,都可以传入
	{
		for (Iterator<?> it = al.iterator(); it.hasNext(); )
		{
			System.out.println(it.next()); //不清楚是什么类型,所以无法使用自定义的getName()方法
		}
	}
	public static <T> void getListT(ArrayList<T> al)  //ArrayList泛型为T,it.next()可返回T数据类型
	{
		for (Iterator<T> it = al.iterator(); it.hasNext(); )
		{
			T t = it.next();  //不清楚是什么类型,所以无法使用自定义的getName()方法
			System.out.println(t); 
		}
	}
}

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值