泛型——(1) 概述、擦除&补偿、集合中的应用

泛型:jdk1.5以后出现的安全机制。

 好处:

         1、将运行时的ClasscastException转到了运行时期。

         2、避免了强制转换的麻烦。

一、将运行时的ClassCastException赚到了运行时期:

 在没有添加泛型的程序中会出现很多的小黄点,以提示程序员存在安全隐患。

 程序运行到第29行时报错Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String。这是因为前面加入的是 "abc" 字符串,取出的时候需要将add( )方法里面添加的object 类型的" abc "转化为String类型。而后来加入的Integer(4)是整数类型的,整数不能转化为String类型,会发生异常。这时我们需要强制程序不能添加 其他类型的元素,就出现了“泛型” 。

加入泛型以后的程序:

添加了泛型以后,元素添加的类型被指定了,其他类型的元素不能被添加进来。将运行时才能发现的异常转到了编译时期。也无需再对数据进行强制类型转换。

二、泛型的示例

<> 尖括号什么时候用? 

      当将要操作的引用数据类型不确定的时候就使用<>。 将要操的 引用数据类型传入即可。其实<>就是一个接受引用数据类型的参数范围。

在程序中只要用到了<>和接口就要明确传入的数据类型引用。

泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。

泛型的擦除:

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。

为什么会擦除呢?

  类在运行的时候首先会被类加载器加载检查。而这类加载器是JDk1.4的, 泛型是JDK1.5以后出现的新特性,所以在加载的时候会擦除。加载完成以后系统会自动进行补偿。泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者在强制转换了。

三、在集合中的应用。

先写一个Person  bean 

package cn.itcast.p2.bean;

public class Person implements Comparable<Person> {

	private String name;
	private int age;
	
	
	public Person() {
		super();
		
	}
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}


	public int compareTo(Person p){
		
//		Person p = (Person)obj;
		int temp = this.age - p.age;
		return temp==0?this.name.compareTo(p.name):temp;
	}
	

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}




	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}


	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}




	@Override
	public String toString() {
		
		return "Person:"+getName()+":"+getAge();
	}
}

 编写一个比较器,主要条件根据名字排序,次要条件根据年龄排序

package cn.itcast.p3.comparator;

import java.util.Comparator;

import cn.itcast.p2.bean.Person;

/*编写一个比较器,主要条件根据名字排序,次要条件根据年龄排序*/
public class ComparatorByName implements Comparator<Person> {

	@Override
	public int compare(Person o1, Person o2) {
		
		int temp = o1.getName().compareTo(o2.getName());
		return temp==0? o1.getAge()-o2.getAge(): temp;
	}

}

创建对象,将比较器作为参数传递。

package cn.itcast.p1.generic.demo;

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

import cn.itcast.p2.bean.Person;
import cn.itcast.p3.comparator.ComparatorByName;

public class GenericDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		TreeSet<Person> ts = new TreeSet<Person>(new ComparatorByName());
		ts.add(new Person("lisi8",21));
		ts.add(new Person("lisi3",23));
		ts.add(new Person("lisi",21));
		ts.add(new Person("lis0",20));
		
		Iterator<Person> it = ts.iterator();
		
		while(it.hasNext()){
			Person p = it.next();
			System.out.println(p.getName()+":"+p.getAge());
		}
	}

}

根据姓名和年龄排序的结果出来:

猜你喜欢

转载自blog.csdn.net/zhanshixiang/article/details/82530533