首页 > 代码库 > JAVA学习第四十一课 — 泛型的基本应用(一)

JAVA学习第四十一课 — 泛型的基本应用(一)


泛型是JDK1.5以后出现的安全机制,简化机制,提高安全性

泛型的优点

1.将运行时出现的问题ClassCastException转移到了编译时期

2.避免了强制转换的麻烦

<>在当操作的引用数据类型不确定的时候使用,将要操作的引用数据类型导入即可,其实<>就是一个用于接收具体引用数据类型的参数范围

在写程序时,只要用到了带<>的类或接口,就必须要明确传人的具体引用数据类型

import java.util.ArrayList;
import java.util.Iterator;
public class Main 
{
<span style="white-space:pre">	</span>public static void main(String[] args) {
<span style="white-space:pre">		</span>ArrayList<String> al = new ArrayList<String>();//明确ArrayList集合只放 字符串
<span style="white-space:pre">		</span>al.add("abc");
<span style="white-space:pre">		</span>al.add("sd");
<span style="white-space:pre">		</span>Iterator<String> it = al.iterator();//迭代器也明确后,下面就不需要强转了
<span style="white-space:pre">		</span>while(it.hasNext()){
<span style="white-space:pre">			</span>String str = it.next();
<span style="white-space:pre">			</span>System.out.println(str);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}
}

泛型技术是给编译器使用的,用于编译时期,是为了确保类的安全,运行时,生成的class文件是不带泛型的,会将泛型去掉,这就是泛型的擦除,擦除的原因是为了兼容运行的类的加载器(如果不擦除也就意味着加载器也要升级,所以要擦除)

因为有了泛型的擦除,也就引出了泛型的补偿技术,在运行时,通过获取元素的类型进行转换动作,就不需要再强制转换了


泛型在集合中的应用

import java.util.Iterator;
import java.util.TreeSet;

public class Man implements Comparable<Man>{
	private int age;
	private String name;
	public Man() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Man(String name,int age) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return super.equals(obj);
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public int compareTo(Man m) {
		// TODO Auto-generated method stub
		int t = this.name.compareTo(m.name);
		return 	t==0?t:this.age-m.age;	
	}
	
}

public class Main 
{
	public static void main(String[] args) {
	
		TreeSet<Man> ts = new TreeSet<Man>();//可以构造一个比较器
		ts.add(new Man("a",1));
		ts.add(new Man("a",4));
		ts.add(new Man("b",5));
		ts.add(new Man("d",2));
		ts.add(new Man("c",7));
		Iterator<Man> it = ts.iterator();
		while(it.hasNext()){
			Man m = it.next();
			System.out.println(m.getName()+","+m.getAge());
		}
	}
}


自定义泛型类

//定义一个工具类操控所有对象
/*public class Tool {
	private Object obj;//为了提高扩展性用Object

	public Object getObj() {
		return obj;
	}

	public void setObj(Object obj) {
		this.obj = obj;
	}
}
*/
//JDK1.5以后  自定义泛型类,当类中操作的引用数据类型不确定的时候,就用泛型来表示
public class Tool<E> {

	private E e;

	public E getObj() {
		return e;
	}

	public void setObject(E obj) {
		this.e = obj;
	}
	
}

public class Student extends Man{//Man类在上面有

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(String name, int age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}
}
public class Worker extends Man {

	public Worker() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Worker(String name, int age) {
		super(name, age);
		// TODO Auto-generated constructor stub
	}
}
public class Main 
{
	public static void main(String[] args) {
		//JDK1.5以前
		/*Tool to  = new Tool();
		to.setObj(new Worker());//一旦不小心传个Worker,编译时,通过,运行时,异常ClassCastException
		Student student = (Student)to.getObj();//但是需要强转*/
		//JDK1.5以后
		Tool<Student> to = new Tool<Student>();
		to.setObject(new Student());//一旦不小心传个Worker,编译就会不通过,和就体现了泛型的好处,检测提到了编译时期
		Student student = to.getObj();
		System.out.println(student.getClass());
	}
}


泛型方法:在方法中定义泛型

class Tool<E> {

	private E e;

	public E getObj() {
		return e;
	}

	public void setObject(E obj) {
		this.e = obj;
	}
	public<O> void show(O str){ //将泛型定义在方法上,传什么类型,就打印什么类型
			System.out.println("Tool.show()"+str);
	}
	public<O> void printf(O str){
		System.out.println("Tool.printf()"+str);
	}
	//public static void mhtod(E e){ }如果是静态访问类上定义泛型,就会编译失败,静态是不需要对象的
	
	//修改,只能将泛型定义方法上
	public static <F> void mthod(F str){
		System.out.println("Tool.mthod()"+str);
	} 
}
public class Main 
{
	public static void main(String[] args) {
		Tool<String> to = new Tool<String>();
		to.show("asd");
		to.show(new Integer(5));
		to.printf("pri");//而printf除了string其他的都不行
		Tool.mthod("哈哈");
		Tool.mthod('f');
	
		}
}


泛型的弊端

上述show方法中,如果传入的是String,无法使用str.length()方法,因为泛型的类型是不确定的,就无法确定到某个类的方法,只能使用一些Object的一些方法


JAVA学习第四十一课 — 泛型的基本应用(一)