Java---不懂泛型怎么用?看这里就行啦,泛型的概述及超详细的应用场景解析~

泛型的引入

  集合可以添加任意类型,所以如果往容器中添加不同的类型,例如String类型和Integer类型,在遍历的时候如果希望访问子类元素所特有的方法,由于元素是Object类型,所以需要向下转型,这个时候如果没有对Object的所有子类做判断,安全隐患永远存在。例如:
  Collection c = new ArrayList();
      c.add(“三国演义”);
      c.add(“西游记”);
      c.add(“红楼梦”);
      c.add(“隔壁老王”);
     c.add(25);

     for (Object obj : c) {
     // System.out.println(obj);
      // 如果我想要使用 元素子类所特有的方法 例如 String的length方法
      String s = (String) obj;
      System.out.println(s + “|” + s.length());
   }

   抛出如下异常:java.lang.ClassCastException

   针对所有的子类使用instanceof做逐一判断,但是又有新的问题,容器可以添加任意类型,如果又来一个学生类,又需要添加elseif语句,不满足开闭原则

for (Object obj : c) {
			if (obj instanceof String) {
				String s = (String) obj;
				System.out.println(s + "|" + s.length());
			} else if (obj instanceof Integer) {
				Integer ii = (Integer) obj;
				System.out.println(ii + "|" + ii.intValue());
			} 
		

  Java提供了泛型
  泛型是模仿方法和数组而来的。

  数组的特点:
    数组在编译时期确定类型
    方法的特点:参数化类型

泛型的概述

  JDK1.5之后引入的新特性,泛型是一种将类型的确定提前到编译时期的一种参数化类型

  格式
    <E>

  泛型的特点:
    1.泛型具备传递性
    2.泛型可以定义多个
    3.泛型只能设置引用数据类型
    4.泛型命名可以是A~Z之间

  泛型的分类
    泛型类: 把泛型定义在类上
    泛型接口: 把泛型定义在接口上
    泛型方法: 把泛型定义在方法上

  泛型的好处:
    1.消除了黄色警告线
    2.去除类型转换,提高了效率
    3.提高了安全性,避免了类型转换异常
    4.简化了代码
    5.提高了代码的扩展和可维护性

代码实例:
Collection<String> c = new ArrayList<String>();
		c.add("三国演义");
		c.add("西游记");
		c.add("红楼梦");
		c.add("隔壁老王");
		
		Iterator<String> it = c.iterator();
		while (it.hasNext()) {
			String s = it.next();
			System.out.println(s + "|" + s.length());
		}
		
		for (String s : c) {
			System.out.println(s);
		}

泛型类

  概述: 把泛型定义在类上

在JDK1.5之前的做法
class GenericClass {
	
	private Object object;

	public Object getObject() {
		return object;
	}

	public void setObject(Object object) {
		this.object = object;
	}
	
}

在JDK1.5之后引入泛型
class GenericClass<E> {
	
	private E e;

	public E getObject() {
		return e;
	}

	public void setObject(E e) {
		this.e = e;
	}
	
}
使用实例:
GenericClass<String> gc = new GenericClass<String>();
		gc.setObject("abc");
		// gc.setObject(18);
		
		/*Object obj = gc.getObject();
		if (obj instanceof String) {
			String s = (String) obj;
			System.out.println(s + "|" + s.length());
		}*/
		String s = gc.getObject();
		System.out.println(s + "|" + s.length());

多个泛型定义的泛型类:
class GenericClass<E, T, H> {
	
	private E e;
	private T t;
	private H h;

	public E getE() {
		return e;
	}

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

	public T getT() {
		return t;
	}

	public void setT(T t) {
		this.t = t;
	}

	public H getH() {
		return h;
	}

	public void setH(H h) {
		this.h = h;
	}
	
}

泛型接口

  概述:把泛型定义在接口上

  使用泛型接口的三种方式:
    1.在实现类的时候确定泛型类型
    2.在实现类的时候不确定泛型类型,在创建接口的时候确定泛型类型
    3.在匿名内部类的时候使用泛型

在实现类的时候确定泛型类型
interface IGenericInterface<E, T> {
	void show(T t);
	void concat(E e, T b);
}


class GenericInterfaceImpl implements IGenericInterface<String, Integer> {

	@Override
	public void show(Integer t) {
		System.out.println(t);
	}

	@Override
	public void concat(String e, Integer b) {
		System.out.println(e + b);
	}
	
}
在实现类的时候不确定泛型类型,在创建接口的时候确定泛型类型
class GenericInterfaceImpl2<E, T> implements IGenericInterface<E, T> {

	@Override
	public void show(T t) {
		System.out.println(t);
	}

	@Override
	public void concat(E e, T b) {
		System.out.println(e);
		System.out.println(b);
	}
	
}

IGenericInterface<String,Integer>gi=newGenericInterfaceImpl2<>();

在匿名内部类的时候使用泛型
IGenericInterface<String, Integer> gi = new IGenericInterface<String, Integer>() {

			@Override
			public void show(Integer t) {
				System.out.println(t);
			}

			@Override
			public void concat(String e, Integer b) {
				System.out.println(e + b);
			}
};
gi.show(100);
gi.concat("abc", 200);

泛型方法

  概述: 把泛型定义方法上

  使用泛型方法: 在方法调用的时候确定泛型

  特点:
    1.泛型方法在方法调用的时候确定类型
    2.泛型方法独立于泛型类,泛型方法又称为局部泛型
    3.泛型方法也可以定义多个

  泛型的应用:
    为什么泛型中的 toArray 设计成一个泛型方法?
    因为设计者并不知道用户往容器中添加什么类型的元素,所以设计为泛型,由调用者确定返回值类型,自己接收

代码示例
Collection<String> c = new ArrayList<>();
		c.add("abc");
		c.add("efg");
	c.add("hij");
// 将集合转换成数组
		String[] strs = c.toArray(new String[] {});
		for (String s : strs) {
			System.out.println(s);
		}
		
		// 将数组转换成集合 T[]
		Integer[] is = {11, 22, 33, 44};
		List<Integer> list = Arrays.asList(is);
		for (Integer ii : list) {
			System.out.println(ii);
	}

泛型限定符

  <?> : 代表任意类型
  <? extends E>: 代表泛型可以是E类型或者E的子类
  <? super T>: 代表泛型可以是 T类型或者是 T 的父类

代码示例
Collection<?> c1 = new ArrayList<String>();
		Collection<?> c2 = new ArrayList<Fu>();
		Collection<?> c3 = new ArrayList<Son>();
		Collection<?> c4 = new ArrayList<Daughter>();
		Collection<?> c5 = new ArrayList<Object>();
		
		Collection<? extends Fu> c6 = new ArrayList<Fu>();
		Collection<? extends Fu> c7 = new ArrayList<Son>();
		Collection<? extends Fu> c8 = new ArrayList<Daughter>();
		// Collection<? extends Fu> c9 = new ArrayList<Object>();
		
		Collection<? super Fu> c10 = new ArrayList<Fu>();
		// Collection<? super Fu> c11 = new ArrayList<Son>();
		// Collection<? super Fu> c12 = new ArrayList<Daughter>();
		Collection<? super Fu> c13 = new ArrayList<Object>();
		
		// boolean addAll(Collection<? extends E> c) 
		Collection<Fu> c = new ArrayList<>();
		Collection<? extends Fu> cc = new ArrayList<Son>();
		Collection<? extends Fu> cc2 = new ArrayList<Daughter>();
		c.addAll(cc);
		c.addAll(cc2);

泛型嵌套

  概述: 泛型里面定义泛型

  需求: 存储如下数据格式:
  一共有三个班
     A班有三个学生
     B班有两个学生
     C班有一个学生

Collection<Student> ac = new ArrayList<Student>();
		ac.add(new Student("张三", 30));
		ac.add(new Student("李四", 35));
		ac.add(new Student("王五", 40));
		
		Collection<Student> bc = new ArrayList<Student>();
		bc.add(new Student("赵六", 30));
		bc.add(new Student("孙七", 35));
		
		Collection<Student> cc = new ArrayList<Student>();
		cc.add(new Student("隔壁老王", 30));
		
		Collection<Collection<Student>> classes = new ArrayList<Collection<Student>>();
		classes.add(ac);
		classes.add(bc);
		classes.add(cc);
		
		/*Iterator<Collection<Student>> iterator = classes.iterator();
		while (iterator.hasNext()) {
			Collection<Student> c = iterator.next();
			Iterator<Student> it = c.iterator();
			while (it.hasNext()) {
				Student s = it.next();
				System.out.println(s.getName() + "|" + s.getAge());
			}
		}*/
		
		for (Collection<Student> collection : classes) {
			for (Student s : collection) {
				System.out.println(s.getName() + "|" + s.getAge());
			}
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值