Java 泛型编程

package com.generic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
	public static void main(String[] args){
		useTool();
		System.out.println();
		useSpecTool();
		System.out.println();
		useSpecFun();
		System.out.println();
		useSpecSuperFun();
		System.out.println();
		useSpecComFun();
		System.out.println();
		useSpecStaticFun();
		System.out.println();
		useInterFun();
		System.out.println();
		useHighLevelFun();
		
	}
	
	/**
	 * 泛型出现之前只好使用Object,具体使用时必须要强制类型转换
	 * 极有可能出现转换类型错误这种运行时异常
	 */
	public static void useTool(){
		try{
			Tool tool = new Tool();
			tool.setObj(new Teacher());
			Teacher tea = (Teacher)tool.getObj();
			System.out.println(tea.print());
			//这里将出现运行时异常
			Student stu = (Student)tool.getObj();
		}catch(Exception e){
			System.out.println("出错!");
		}
	}
	
	public static void useSpecTool(){
		//使用泛型之后可以提早发现出错源头,提高安全性
		//注意,只能对引用数据类型不确定时使用,基本类型无效(只针对对象)
		SpecTool<Teacher> sepcTool = new SpecTool<Teacher>();
		sepcTool.setObj(new Teacher());
		Teacher tea = sepcTool.getObj();
		System.out.println(tea.print());
		
		//使用泛型之后将产生编译时错误,可及早发现
		//sepcTool.setObj(new Student());
	}
	
	public static void useSpecFun(){
		//使用泛型,制定之后即可在方法中使用
		SpecFun<Integer> fun = new SpecFun<Integer>();
		fun.show(100);
		fun.print(3232);
		//使用错误的类型将会导致编译时异常
		//fun.show("shit");
	}
	
	public static void useSpecSuperFun(){
		SpecSuperFun fun = new SpecSuperFun();
		//使用泛型方法,可以单独为每个方法制定不同的输入类型
		fun.show("ddddddd");
		fun.show(new Teacher());
		fun.show(100);
		fun.print(new Student());
	}
	
	public static void useSpecComFun(){
		SpecComFun<String> fun = new SpecComFun();
		fun.show("ddddddd");
		//一旦指定了泛型类,则使用了类指定泛型的方法只能使用该类型,否则将产生编译时错误
		//fun.show(new Teacher());
		//而没有指定类泛型的方法可以任意使用任何类型
		fun.print(new Student());
		fun.print(200);
	}
	
	public static void useSpecStaticFun(){
		SpecStaticFun<String> fun = new SpecStaticFun();
		fun.show("ddddddd");
		//静态方法可以直接使用类调用,所以静态方法的泛型必须指定为泛型方法
		SpecStaticFun.print("sssss");
		SpecStaticFun.print(new Teacher());
	}
	
	public static void useInterFun(){
		//使用已经指定类型的实现类,则具体使用时的类型必须和实现的类型一样,否则出编译时错误
		//Inter<Integer> inter = new InterImpl();
		Inter<String> inter = new InterImpl();
		inter.show("22222");
		//继承类也可以不指定实现的类型,这样就可以在具体使用时自由指定
		Inter<Integer> inter2 = new InterImpl2<Integer>();
		Inter<Teacher> inter3 = new InterImpl2<Teacher>();
	}
	
	public static void useHighLevelFun(){
		List<String> l1 = new ArrayList<String>();
		l1.add("l-111");
		l1.add("l-222");
		
		List<High> high = new ArrayList<High>();
		high.add(new High());
		high.add(new High());
		
		List<Middle> middle = new ArrayList<Middle>();
		middle.add(new Middle());
		middle.add(new Middle());
		
		List<Low> low = new ArrayList<Low>();
		low.add(new Low());
		low.add(new Low());
		
		high.add(new Low());

		//直接的?可以接受任意类型
		print(l1);
		print2(l1);
		print(high);
		print(middle);
		print(low);
		//? extends T 可以接受T以及T的所有子类
		//print3(high);   	//编译期错误
		print3(middle);
		print3(low);
		//? super T 可以接受T以及T的所有父类
		print4(high);   
		print4(middle);
		//print4(low);		//编译期错误
		
	}
	//不明确传入的类型的时候可以使用“?”占位符,仅仅作为站位用
	//这样就表示任何传入的list都可以接受
	private static void print(List<?> list){
		Iterator<?> it = list.iterator();
		while(it.hasNext()){
			System.out.print(it.next() + "  ");
		}
		System.out.println();
	}
	//使用这种方法的话就可以在方法中具体使用“T”类型,但是“?”占位符的方法就不可以
	private static <T> void print2(List<T> list){
		Iterator<T> it = list.iterator();
		while(it.hasNext()){
			System.out.print(it.next() + "  ");
		}
		System.out.println();
	}
	//通配符向上限定,可以接受Middle类或者Middle类的子类
	private static void print3(List<? extends Middle> list){
		Iterator<? extends Middle> it = list.iterator();
		while(it.hasNext()){
			System.out.print(it.next() + "  ");
		}
		System.out.println();
	}
	//通配符向下限定,可以接受Middle类或者Middle类的子类
	private static void print4(List<? super Middle> list){
		Iterator<? super Middle> it = list.iterator();
		while(it.hasNext()){
			System.out.print(it.next() + "  ");
		}
		System.out.println();
	}
}

class Teacher{
	public String print(){
		return "TTTTTTT";
	}
	
	public String toString(){
		return "Teacher!!!!!";
	}
}

class Student{
	public String print(){
		return "SSSSSSS";
	}
	public String toString(){
		return "Student!!!!!";
	}
}






/**
 * 出现泛型之前的做法,使用Object
 */
class Tool{
	private Object obj;

	public final Object getObj() {
		return obj;
	}

	public final void setObj(Object obj) {
		this.obj = obj;
	}
}



/**
 * 泛型类:
 * 使用泛型,由使用者决定使用什么类型
 * 尖括号里面的命名可以随便起
 */
class SpecTool<BalaBala>{
	private BalaBala obj;

	public final BalaBala getObj() {
		return obj;
	}

	public final void setObj(BalaBala obj) {
		this.obj = obj;
	}
}



/**
 * 泛型类定义的类型,在整个类之中都有效,如果被方法使用
 * 一旦指定,则所有方法要操作的类型则已经指定
 */
class SpecFun<T>{
	public void show(T t){
		System.out.println("show:" + t);
	}
	public void print(T t){
		System.out.println("print:" + t);
	}
}


/**
 * 泛型方法:
 * 如果使用泛型方法,则可以让不同的方法使用不同的类型
 * 具体针对某个方法使用泛型的时候有,可以在每个方法上加上泛型
 * 尖括号中的泛型命名依然可以随便制定
 * 注意:泛型符号放在返回值类型之前!!
 */
class SpecSuperFun{
	public <T> void show(T t){
		System.out.println("show:" + t);
	}
	public <SHIT> void print(SHIT t){
		System.out.println("print:" + t);
	}
}



/**
 * 还可以同时使用泛型类和泛型方法,并不会产生问题
 * 注意:泛型符号放在返回值类型之前!!
 */
class SpecComFun<T>{
	public void show(T t){
		System.out.println("show:" + t);
	}
	public <SHIT> void print(SHIT t){
		System.out.println("print:" + t);
	}
}



/**
 * 静态泛型方法:
 * 注意:静态方法不可以使用类定义的泛型
 * 因为类未被实例化的时候,其泛型类型还未被指定,静态方法不能使用未确定的类型
 * 所以静态方法的泛型只能在方法上指定
 * 注意:泛型符号放在返回值类型之前!!
 */
class SpecStaticFun<T>{
	public void show(T t){
		System.out.println("show:" + t);
	}
	public static <SHIT> void print(SHIT t){
		System.out.println("print:" + t);
	}
}



/**
 * 接口定义泛型
 */
interface Inter<T>{
	void show(T t);
}
/**
 * 第一种应用于接口上的泛型使用方法
 * 也即在实现接口的同时就指定泛型的类型
 */
class InterImpl implements Inter<String>{
	@Override
	public void show(String t) {
		System.out.println("hahah show:" + t);
	}
}
/**
 * 第二中应用与接口上的泛型使用方法
 * 也即实现类上面也是用泛型,注意泛型的名字必须要和接口一样
 * @author Feng
 *
 * @param <T>
 */
class InterImpl2<T> implements Inter<T>{
	@Override
	public void show(T t) {
		System.out.println("wulawula show:" + t);
	}
}



/**
 * 三个类具有连续继承关系,在使用泛型限定(向上or向下)的时候可以:
 * 通配符:?				(接受所有类型)
 * 向上限定:? extends T	(仅接受T或者T的子类)
 * 向下限定:? super T		(仅接受T或者T的父类)
 * 例如:
 * 	Student和Worker继承Person
 * 1、向上限定:
 * 	TreeSet<Student> TreeSet<Worker> 两个Set都需要排序,都需要比较器,但只需要一个就可以了
 * 	Comparator<Person>
 * 	也即
 * 	class Comp implements Comparator<Person>
 * 	TreeSet<Student> stu = new TreeSet<Student>(new Comp());
 * 	TreeSet<Worker> stu = new TreeSet<Worker>(new Comp());
 * 2、向下限定:
 * 	链表中需要加入所有的Person
 * 	List<Person> per = new ArrayList<Person>();
 * 	per.addAll(new List<Student>());
 * 	per.addAll(new List<Worker>());
 */
class High{
	public String toString() {
		return "High!!";
	}
}
class Middle extends High{
	public String toString() {
		return "Middle!!";
	}
}
class Low extends Middle{
	public String toString() {
		return "Low!!";
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值