
正文
JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
不知不觉JAVA之旅已经写到21篇了,不得不感叹当初自己坚持要重学一遍JAVA的信念,中途也算是非常的痛苦吧,不过熬到现在,已经算是有点效果了,继续加油,估计三十来篇就能结束自己的JAVA之旅了,go,go!
一.泛型的概述什么是泛型,我们可以用一个很典型的例子来说明
不知不觉JAVA之旅已经写到21篇了,不得不感叹当初自己坚持要重学一遍JAVA的信念,中途也算是非常的痛苦吧,不过熬到现在,已经算是有点效果了,继续加油,估计三十来篇就能结束自己的JAVA之旅了,go,go!
什么是泛型,我们可以用一个很典型的例子来说明
package com.lgl.hellojava;import java.util.ArrayList;import java.util.Iterator;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { /** * 泛型 */ ArrayList al = new ArrayList(); al.add("hello 1"); al.add("hello 02"); al.add("hello 0300"); al.add("hello 084"); //添加int al.add(5); Iterator iterator = al.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); // 打印长度 sop(s.length()); } } // 输出 public static void sop(Object obj) { System.out.println(obj); }}
这里,我们用一个arraylist存储的数据有String也有int,输出的结果

不会发现,他报的就是类型的异常,我们要怎么去解决?这里就牵扯出泛型来了
- 泛型:JDK1.5版本之后出现的新特性,用于解决安全问题,是一个安全机制;
我们要怎么使用?
ArrayList<String> al = new ArrayList<String>();
我定义了一个容器,容器的参数是String类型,规范了数据类型,就不能存其他的数据了,安全性提高了!
- 好处:讲运行时期出现的问题转移到了编译时期,方便程序员解决问题,让运行时期问题减少,安全
二.泛型的使用泛型的格式:通过<>来定义要操作的引用数据类型,在使用JAVA提供的对象时,什么时候写泛型呢,通常在集合框架中很常见,只要见到<>就是定义泛型!
其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型,作为参数,传递到<>一样 ,我们来个小例子
泛型的格式:通过<>来定义要操作的引用数据类型,在使用JAVA提供的对象时,什么时候写泛型呢,通常在集合框架中很常见,只要见到<>就是定义泛型!
其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型,作为参数,传递到<>一样 ,我们来个小例子
package com.lgl.hellojava;import java.util.Comparator;import java.util.Iterator;import java.util.TreeSet;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { TreeSet<String> tr = new TreeSet<String>(new LenComp()); tr.add("hello 01"); tr.add("hello 012"); tr.add("hello 013"); tr.add("hello 014"); Iterator<String> iterator = tr.iterator(); while (iterator.hasNext()) { String string = iterator.next(); sop(string); } } // 输出 public static void sop(Object obj) { System.out.println(obj); }}// 比较器class LenComp implements Comparator<String> { @Override public int compare(String o1, String o2) { String s1 = o1; int num = new Integer(o1.length()).compareTo(new Integer(o2.length())); if (num == 0) { return o1.compareTo(o2); } return num; }}
你可以仔细的看看里面是怎么用泛型的,就是一些小技巧
三.泛型类这是我们优化代码比较常见的一种方式,我们可以看这块代码
这是我们优化代码比较常见的一种方式,我们可以看这块代码
package com.lgl.hellojava;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { Tool t = new Tool(); t.setW(new Worker()); t.getW(); } // 输出 public static void sop(Object obj) { System.out.println(obj); }}//操作工人的工具类class Tool { private Worker w; public Worker getW() { return w; } public void setW(Worker w) { this.w = w; }}class Worker {}
这里,有一个工人的类,我们定义一个工具类去操作,对吧,这个逻辑就是这么的简单,但是你回发现,如果我在定义一个学生的类,就又得需要一个学生的工具类了,我们为什么不去合并这个工具类,抽调共有的方法呢?你会说可以用Object?
//操作工人的工具类class Tool { private Object obj; public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; }}
这样的话,你如果传递的话,还是要定义床底类型,不然会报类型异常的,我们泛型的用法
class Utils<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; }}
由你来指定传递进来的参数,这样就可以为所欲为了
- 什么时候定义泛型类
当类中要操作的引用数据类型不确定的时候,早起定义Object来完成扩展,现在定义泛型来完成扩展
四.泛型方法泛型除了定义在类中,还是可以定义在方法上的,我们来看一下
泛型除了定义在类中,还是可以定义在方法上的,我们来看一下
package com.lgl.hellojava;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { Demo<String> d = new Demo<String>(); d.show("hh"); d.print("aa"); }}class Demo<T> { public void show(T t) { System.out.println("show:" + t); } public void print(T t) { System.out.println("print:" + t); }}
泛型类定义的泛型,在整个类中有效,如果被方面使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
- 为了让不同的方法可以操作不同的类型,而且类型不确定,那么可以将泛型定义在方法上
仔细看
class Demo { public <T> void show(T t) { } public <T>void print(T t){ }}
这样就可以传递泛型参数了
五.静态泛型方法这个倒不是什么大知识点,就是注意一下,泛型方法不能使用静态的,也可以说静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上,就可以了
这个倒不是什么大知识点,就是注意一下,泛型方法不能使用静态的,也可以说静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上,就可以了
class Demo<T> { public <T> void show(T t) { } public <T> void print(T t) { } public static <T> void method(T t) { }}
要放在static后面哦!
六.泛型接口你类和方法都有了,怎么能少得了接口呢?
你类和方法都有了,怎么能少得了接口呢?
package com.lgl.hellojava;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { InterImpl<Integer> i = new InterImpl<Integer>(); i.show(55); }}class InterImpl<T> implements Inter<T> { @Override public void show(T t) { System.out.println("show:" + t); }}interface Inter<T> { void show(T t);}
结构也差不多,传参数就行,但是这种情况是不多见的
七.泛型限定我们来玩玩泛型的高级用法,go
先从例子切入正题
我们来玩玩泛型的高级用法,go
先从例子切入正题
package com.lgl.hellojava;import java.util.ArrayList;import java.util.Iterator;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("hello 01"); al.add("hello 02"); al.add("hello 03"); al.add("hello 04"); ArrayList<Integer> all = new ArrayList<Integer>(); all.add(9); all.add(596); all.add(98); all.add(97); printColl(all); } //内容不明确 public static void printColl(ArrayList<?> als) { Iterator<?> iterator = als.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } }}
问号是占位符,上面的逻辑就是我们有两个arrayList,但是我们需要公用一个方法,内容不明确,所以用问号占位,其实实现的方式还有很多种,还有一种需求使用不到?的,因为?是打印任何的数据,但是我只需要打印限定的几种类型,这个时候该怎么做?
package com.lgl.hellojava;import java.util.ArrayList;import java.util.Iterator;//公共的 类 类名public class HelloJJAVA { public static void main(String[] args) { ArrayList<Person> al = new ArrayList<Person>(); al.add(new Person("zhangsan")); al.add(new Person("lisi")); al.add(new Person("wangwu")); ArrayList<Student> al1 = new ArrayList<Student>(); al1.add(new Student("zhangsan -- 1")); al1.add(new Student("lisi -- 2")); al1.add(new Student("wangwu -- 3")); // ArrayList printColl(al1); } // 内容不明确 public static void printColl(ArrayList<? extends Person> als) { Iterator<? extends Person> iterator = als.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getName()); } }}class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }}class Student extends Person { public Student(String name) { super(name); }}
这里,就能打印出学生和人类,而不打印其他类型的参数了,这就叫泛型限定
- ?叫通配符,也可以理解为占位符
- 泛型的限定 ? extends E:E类型和E的子类型。这叫上限
- ? super E:可以接受E类型和E的父类,这叫下限
下限我就不演示了,有机会的同学可以自己试试看,还是挺好玩的
好的,我们本篇文章就到这里OK了,下一篇聊聊Map吧,恩,下篇再见







