JAVASE之泛型
2015-01-21 21:05
162 查看
泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制
eg:ArrayList<String> al = new ArrayList<String>();
集合加上泛型后,该集合只能存储String类型的值,若存储其他类型的值,在编译时期将报错
好处:
1、将运行时期出现问题ClassCastException,转移到了编译时期
方便于程序员解决问题,让运行时期问题减少,安全
2、避免了强制转换麻烦
通俗点看:其实 <> 就是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
泛型出现前后的做法:
泛型类定义的泛型,在整个类中有效,如果被方法使用
那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了
为了让不同方法可以操作不同类型,而且类型不确定
可以将泛型定义在方法上
特殊方法:
静态方法不可以访问类上定义的泛型-
--------只有对象才能带着类型去运行,静态比对象先加载
如果静态方法操作的引用数据类型,可以将泛型定义在方法上
演示:
泛型的限定:
? extends E 表示可以接受E类型或者E的子类型,上限
? super E 表示可以接受E类型或者E的父类型 下限
例子:
addAll(Collection<? extends E>comparator)----->添加可以添加E或者E的子类型
TreeSet(Comparator<? super E>comparator)--->比较的时候比较的类型和其父类型都能接受子类对象进来,兼容
比较器的泛型限定:
因为传到比较器时,你传来的是Student,所以比较器上肯定是Student或Student的父类型
也就是说implements Comparable< > 这里的类型要大于传进来的类型所以是?Super E
当执行ts.add(new Student("abc01"));传进来的是Student类型,所以比较器是Student或者Student的父类型才可以接收,
但是,当有两级继承时候 爷--父--孙----implements Comparable< >这里的参数必须要统一,所以直接整爷爷的类型
eg:ArrayList<String> al = new ArrayList<String>();
集合加上泛型后,该集合只能存储String类型的值,若存储其他类型的值,在编译时期将报错
好处:
1、将运行时期出现问题ClassCastException,转移到了编译时期
方便于程序员解决问题,让运行时期问题减少,安全
2、避免了强制转换麻烦
通俗点看:其实 <> 就是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
泛型出现前后的做法:
class Worker { ... } //泛型前做法 class Tool { private Object obj; public void setObject(Object obj) { this.obj = obj; } public Object getObject() { return obj; } } //什么时候定义泛型类 //当类中要操作的引用数据类型不确定的时候,基本数据类型不确定定义不了 //早期定义Object来完成扩展,因为Object是祖宗 class Utils { private QQ q; public void setObject(QQ q) { this.q = q; } public QQ getObject() { return q; } } class GenericDemo3 { public static void main(String[] args) { Utils u = new Utils(); u.setObject(new Worker();) Worker w = u.getObject(); } }
泛型类定义的泛型,在整个类中有效,如果被方法使用
那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了
class Demo { public void show(T t) { System.out.println("show:"+t); } public void print(T t) { System.out.println("print:"+t); } }
为了让不同方法可以操作不同类型,而且类型不确定
可以将泛型定义在方法上
特殊方法:
静态方法不可以访问类上定义的泛型-
--------只有对象才能带着类型去运行,静态比对象先加载
如果静态方法操作的引用数据类型,可以将泛型定义在方法上
演示:
class Demo//也可以定义在接口上,用法和类一样 { public void show(T t) { System.out.println("show:"+t); } public void print(Q q) //Q就相当于形参,可以是任意的 { System.out.println("print:"+q); } public static void method(W t) { System.out.println("method:"+t); } } class GenericDemo4 { public static void main(String[] args) { Demo d = new Demo(); d.print(9);//自动装箱类型,将其转换为Integer d.show("shdk");//失败,当new对象时不加泛型则正确 //由于泛型定义在方法上,所以下面两条语句都正确 d.print(5); d.print("sfd"); //静态方法的泛型 Demo.method("hahahhaha"); } }
泛型限定
? 通配符 也可以理解为占位符//通配符的意义就是无论是什么泛型都可以打印,Integer和String的都可以打印 public static void printColl(ArrayList<?> al) { Iterator<?> it = al.iterator(); while(it.hasNext()) { System.out.println(it.next()); } }
泛型的限定:
? extends E 表示可以接受E类型或者E的子类型,上限
? super E 表示可以接受E类型或者E的父类型 下限
例子:
addAll(Collection<? extends E>comparator)----->添加可以添加E或者E的子类型
TreeSet(Comparator<? super E>comparator)--->比较的时候比较的类型和其父类型都能接受子类对象进来,兼容
import java.util.*; class GenericDemo6 { public static void main(String[] args) { ArrayList al1 = new ArrayList(); al1.add(new Person("lisi01")); al1.add(new Person("lisi02")); al1.add(new Person("lisi03")); Iterator it = ts.iterator(); while(it.hasNext()) { System.out.println(it.next().getName()); } } public static void printColl(ArrayList<? extends Person> al) { /*如果仅仅是Person的话,不能传入Person的子类Student,所以也可以是 ? Super Student, 区别: 若是<? extends Person>,则提供的方法必须是父类的 若是<? Super Student>,调用方法时,还需要进行强转,因为Object也是父类 */ Iterator<? extends Person> it = al.iterator(); while(it.hasNext()) { System.out.println(it.next().getName()); } } } class Person { private String name; Person(String name) { this.name = name; } public String getName() { return name; } }
比较器的泛型限定:
class Person { private String name; Person(String name) { this.name = name; } public String getName() { return name; } } class Student extends Person implements Comparable//<? super E>,既可以比较学生,也可以比较学生的父类 { Student(String name) { super(name); } public int compareTo(Person s) { System.out.println("niininin"); return 1; } } //比较器 class Comp implements Comparator//所以,也可以是Person { public int compare(Student s1,Student s2) { return s1.getName().compareTo(s2.getName()); } } //既能比较Student,也可以比较Student的父类型 TreeSet ts = new TreeSet(new Comp()); ts.add(new Student("abc01")); ts.add(new Student("cdf03d"));
因为传到比较器时,你传来的是Student,所以比较器上肯定是Student或Student的父类型
也就是说implements Comparable< > 这里的类型要大于传进来的类型所以是?Super E
当执行ts.add(new Student("abc01"));传进来的是Student类型,所以比较器是Student或者Student的父类型才可以接收,
但是,当有两级继承时候 爷--父--孙----implements Comparable< >这里的参数必须要统一,所以直接整爷爷的类型
相关文章推荐
- JavaSE入门学习40:Java集合框架之泛型
- 博为峰Java技术题 ——JavaSE 泛型Ⅲ
- JavaSE-泛型机制
- JavaSE(9):java集合与泛型
- JavaSE复习_8 泛型程序设计
- JavaSE基础:学习泛型
- 博为峰Java技术题 ——JavaSE 泛型Ⅳ
- 【JavaSE】day04_Collection_Iterator_新循环_泛型
- 博为峰Java技术题 ——JavaSE 泛型Ⅰ
- JavaSE 详细了解泛型中的边界问题
- JavaSE基础学习笔记-提高篇-JDK1.5新特性-泛型
- javaSE-泛型
- JavaSE学习笔记--泛型
- 【JavaSE系列-基础篇6】——为什么使用泛型?
- 博为峰Java技术题 ——JavaSE 泛型Ⅱ
- 【JavaSE系列-基础篇6】——泛型类型
- javaSE之多态参数与泛型
- 黑马程序员-JAVASE入门(泛型)
- JavaSe基础(25)-- 泛型
- JavaSE第五十四讲:自定义泛型与泛型的常见陷阱