28.复习泛型的一些知识

  • 初识泛型
  • 了解泛型
  • 泛型类
  • 泛型方法
  • 泛型接口(不常用)
  • 泛型限定

#初识泛型

  1. 泛型是JDK1.5引入的新特性,用于解决类型安全问题
  2. 好处:编译时提前发现可能存在的类型转换异常;避免强制转换的麻烦
  3. 所谓泛型,就是变量类型的参数化
  4. API文档中,有<>尖括号的地方,就可以使用泛型
import java.util.TreeSet;

public class Test {
	public static void main(String[] args) {
		TreeSet<String> ts = new TreeSet<String>();
		ts.add("1");
		ts.add("2");
		ts.add("3");
		System.out.println(ts);
	}
}


#了解泛型

ArrayList< E > 类定义和ArrayList< Integer > 类引用中涉及的术语

  1. 整个称为ArrayList< E >泛型类型
  2. ArrayList< E > 中的E称为类型变量或类型参数
  3. 整个ArrayList< Integer > 称为参数化的类型
  4. ArrayList< Integer > 中的Integer 称为类型参数的实例实际类型参数
  5. ArrayList< Integer > 中的**<> 念着typeof**
  6. ArrayList 称为原始类型
  7. 参数化类型不考虑类型参数的继承;创建数组实例时,数组的元素不能使用参数化的类型
Vector<String> v = new Vector<Object>(); //错误
Vector<Object> v = new Vector<String>(); //也错误
Vector<Integer> vectorList[] = new Vector<Integer>[10];//错误

#泛型类
当类中操作的引用数据类型不确定时,我们可以自定义泛型类。

class Tools<T>
{
}
public class Test {
	public static void main(String[] args) {
		new Tools<String>().sop("test.");
	}
}

class Tools<T> {
	public void sop(T t) {
		System.out.println(t);
	}
}

  看上面的程序,在定义Tools类时,不知道要操作的是什么类型,因此将Tools定义为泛型类,到使用时确定操作对象为String类型,就将类型参数指定为String了。


#泛型方法
  泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。

public <T> void show(T t) 
// 注意:<>放在修饰符后面,返回值前面
{
}
public class Test {
	public static void main(String[] args) {
		Tool_A<String> a = new Tool_A<String>();
		a.sop("a");
		a.sop(1); //编译时报错
		a.show(1.2222);
		
		Tool_B b = new Tool_B();
		b.show("a");
		b.show(1);
	}
}

class Tool_A<T> {
	// 该类A是泛型类,这个sop方法根据类型参数,确定运行时操作的类型
	public void sop(T t) {
		System.out.println("Tool_A sop:  " + t);
	}

	// 泛型类和泛型方法可以同时定义,且不冲突。这个show方法是泛型方法,,可以接收不同的类型
	public <T> void show(T t) {
		System.out.println("Tool_A show:  " + t);
	}
}

class Tool_B {
	// 如果既不是泛型类,又不是泛型方法,方法参数的类型必须确定
	public void show(String t) {
		System.out.println("Tool_B show:  " + t);
	}

	// 该类B不是泛型类,这个show方法是泛型方法,可以接收不同的类型
	public <T> void show(T t) {
		System.out.println("Tool_B show:  " + t);
	}
}

特殊情况

class Tool_A<T> {

	public static void method(T t) { //错,静态方法不可以访问定义类上的泛型
	}

	public static <T> void method(T t) {//对,如果静态方法操作的引用数据类型不确定,可将泛型定义在方法上
	}

}

#泛型接口

class Aclass implements A<String>{

	@Override
	public void sop(String t) {
		// TODO Auto-generated method stub
	}

}

interface A<T>{
	public abstract void sop(T t);
} 

  泛型还能定义在接口上,如果定义泛型接口后还是不知道什么类型,可以将实现类继续定义为泛型类,由实现类确定具体类型。


#泛型限定

  1. < ? >代表通配符,用于接收不确定的类型
  2. < ? extends E > : 可以接收E类型或者E的子类型。
  3. < ? super E >: 可以接收E类型或者E的父类型。
import java.util.*;

public class Test {
	public static void main(String[] args) {
		ArrayList<String> al1 = new ArrayList<String>();
		al1.add("AL1");
		al1.add("AL2");
		al1.add("AL3");

		ArrayList<Integer> al2 = new ArrayList<Integer>();
		al2.add(1);
		al2.add(2);
		al2.add(3);
		
		printCollection(al1);
		printCollection(al2);
	}

	public static void printCollection(ArrayList<?> al) { 
		Iterator<?> it = al.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

  这个程序,如果printCollection(ArrayList< ? > al)改为printCollection(ArrayList< T > al)会出错,因为上面**< T >这种形式是在声明泛型的类或方法的时候限制了可以用的泛型类型;而< ? >形式是在使用的时候限制**了引用的类型。

//对上面的程序来说,以下情况两句printCollection都错
printCollection(ArrayList<T> al) {    ×
//对上面的程序来说,以下情况printCollection(al1);错
printCollection(ArrayList<Integer> al) {    ×
import java.util.*;

public class Test {
	public static void main(String[] args) {
		//TreeSet(Comparator<? super E> comparator) 
		TreeSet<Student> ts = new TreeSet<Student>(new PersonComparator());
		ts.add(new Student(12));
		ts.add(new Student(14));
		ts.add(new Student(13));
		System.out.println(ts);//[12, 13, 14]
	}
}

class Person {
	public int age;
}

class Student extends Person {
	public Student(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return Integer.toString(this.age);
	}
}

class PersonComparator implements Comparator<Person> {
	@Override
	public int compare(Person p1, Person p2) {
		return new Integer(p1.age).compareTo(new Integer(p2.age));
	}
}

  上面的程序,由于TreeSet指定的比较器使用了泛型限定TreeSet(Comparator< ? super E > comparator) ,因此就算再写一个Person的子类Worker,也可以直接继续用这个比较器,很方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值