Java Generic application

三、泛型概述和基本使用

* A:泛型概述

* 泛型的由来:通过Object转型问题引入
* 早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。

 1 /*Person类 父类*/ 2 public class Person {  3 private String name;  4 private int age;  5 public Person() {  6 super();  7  8  }  9 public Person(String name, int age) { 10 super(); 11 this.name = name; 12 this.age = age; 13  } 14 public String getName() { 15 return name; 16  } 17 public void setName(String name) { 18 this.name = name; 19  } 20 public int getAge() { 21 return age; 22  } 23 public void setAge(int age) { 24 this.age = age; 25  } 26 27 } 28 29 /*Student 类继承Person类*/30 public class Student extends Person { 31 32 public Student() { 33  } 34 35 public Student(String name, int age) { 36 super(name, age); 37 38  } 39 40 } 41 /*Tool class*/42 43 public class Tool { 44 private Object q; 45 46 public Object getObj() { 47 return q; 48  } 49 50 public void setObj( ) { 51 this.q = q; 52  } 53 54 55 } 56 57 /*Work class extends Person*/58 public class Worker extends Person { 59 60 public Worker() { 61  } 62 63 public Worker(String name, int age) { 64 super(name, age); 65 66  } 67 68 } 69 70 71 /*invoke class*/72 public static void demo1() { 73 Tool t = new Tool (); //创建工具类对象74 t.setObj(new Student("张三",23)); 75 76 //Worker w = (Worker) t.getObj(); //向下转型,但是 77 //Object是超类无法转型 78 //System.out.println(w);79  } 80 81 /**82  上方会报错,因为传入是Student类型但是接受的是Work类型,导致类型不一致 83 解决办法是用泛型指定Tool是Student类,这样就可以实现强转 84 */

解决方法:

public static void demo1() { Tool<Student> t = new Tool<>(); //创建工具类对象 t.setObj(new Student("张三",23)); //Worker w = (Worker) t.getObj(); //向下转型 //System.out.println(w); } /* improve Tool class*/public class Tool<Q> { private Q q; public Q getObj() { return q; } public void setObj(Q q) { this.q = q; } }  

扫盲点:

技术分享图片
技术分享图片

public class Tool<Q> { private Q q; public Q getObj() { return q; } public void setObj(Q q) { this.q = q; } public<T> void show(T t) { //方法泛型最好与类的泛型一致 System.out.println(t); //如果不一致,需要在方法上声明该泛型 } public static<W> void print(W w) { //静态方法必须声明自己的泛型 System.out.println(w); } 

View Code

在接口中实现泛型

技术分享图片
技术分享图片

interface Inter<T> { public void show(T t);}/*class Demo implements Inter<String> { //推荐用这种 @Override public void show(String t) { System.out.println(t); } }*/class Demo<T> implements Inter<T> { //没有必要在实现接口的时候给自己类加泛型 @Override public void show(T t) { System.out.println(t); } }

View Code

 

 泛型中高级通配符的运用

/**
* * A:泛型通配符<?>
* 任意类型,如果没有明确,那么就是Object以及任意的Java类了
* B:? extends E       
* 向下限定,E及其子类
* C:? super E
* 向上限定,E及其父类
*/

B:

技术分享图片
技术分享图片

 1 public static void main(String[] args) { 2 //List<?> list = new ArrayList<Integer>(); //当右边的泛型是不确定时,左边可以指定为? 3 ArrayList<Person> list1 = new ArrayList<>(); 4 list1.add(new Person("张三", 23)); 5 list1.add(new Person("李四", 24)); 6 list1.add(new Person("王五", 25)); 7  8 ArrayList<Student> list2 = new ArrayList<>(); 9 list2.add(new Student("赵六", 26));10 list2.add(new Student("周七", 27));11 12  list1.addAll(list2);13  System.out.println(list1);14 15 }

View Code

C:

技术分享图片
技术分享图片

 1 public static void main(String[] args) { 2 //demo1(); 3 TreeSet<Student> ts1 = new TreeSet<>(new CompareByAge()); 4 ts1.add(new Student("张三", 33)); 5 ts1.add(new Student("李四", 13)); 6 ts1.add(new Student("王五", 23)); 7 ts1.add(new Student("赵六", 43)); 8  9 TreeSet<BaseStudent> ts2 = new TreeSet<>(new CompareByAge());10 ts2.add(new BaseStudent("张三", 33));11 ts2.add(new BaseStudent("李四", 13));12 ts2.add(new BaseStudent("王五", 23));13 ts2.add(new BaseStudent("赵六", 43));14 15  System.out.println(ts2);16  }17 18 // public static void demo1() {19 // ArrayList<Student> list1 = new ArrayList<>();20 // list1.add(new Student("张三", 23));21 // list1.add(new Student("李四", 24));22 // 23 // ArrayList<BaseStudent> list2 = new ArrayList<>();24 // list2.add(new BaseStudent("王五", 25));25 // list2.add(new BaseStudent("赵六", 26));26 // 27 // list1.addAll(list2);28 // }29 30 31 32 33 class CompareByAge implements Comparator<Student> {34 35  @Override36 public int compare(Student s1, Student s2) {37 int num = s1.getAge() - s2.getAge();38 return num == 0 ? s1.getName().compareTo(s2.getName()) : num;39  }40 41 }

View Code

B,C 原理解释图

技术分享图片

 

技术分享图片

 

* B:泛型好处
* 提高安全性(将运行期的错误转换到编译期) 
* 省去强转的麻烦
* C:泛型基本使用
* <>中放的必须是引用数据类型 
* D:泛型使用注意事项
* 前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)

 

相关文章