Java

为什么要使用泛型:

 1 /**
 2  * 功能:泛型的使用,解释为什么使用泛型
 3  */
 4 package generic;
 5 
 6 import java.util.ArrayList;
 7 import java.util.Iterator;
 8 
 9 public class GenericTest01
10 {
11     public static void main(String[] args)
12     {
13         genericDemo();
14         // genericDemo2();
15     }
16     
17     // 没有使用泛型
18     public static void genericDemo()
19     {
20         ArrayList al = new ArrayList();
21         al.add("qwe");
22         // 上面添加的字符串,下面添加的是int,迭代时肯定会报类型转换异常
23         al.add(4);
24         
25         Iterator it = al.iterator();
26         while(it.hasNext())
27         {
28             // 需要强制类型转换
29             // 此处在运行时会报类型转换异常:ClassCastException
30             // 在编译时不会报异常
31             String s = (String)it.next();  // 1
32             System.out.println(s + ":" + s.length());
33         }
34         
35         /**
36          * 当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,该对象的编译类型变成了Object类型,
37          * 但其运行时类型任然为其本身类型;
38          * 因此,//1 处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现"java.lang.ClassCastException"异常;
39          */
40     }
41     
42     // JDK1.5之后使用泛型
43     // 解决安全问题
44     public static void genericDemo2()
45     {
46         // 指定只添加String类型数据
47         ArrayList<String> al = new ArrayList<String>();
48         al.add("qwe");
49         // 编译时下面这条语句就报错了
50         // al.add(4);
51         
52         // 迭代器也通过泛型指定类型
53         // 后续就不需要强制类型转换了
54         Iterator<String> it = al.iterator();
55         while(it.hasNext())
56         {
57             String s = it.next();
58             System.out.println(s + ":" + s.length());
59         }
60     }
61 }
泛型的使用,解释为什么使用泛型

什么是泛型:

自定义泛型类:

 1 /**
 2  * 自定义泛型类
 3  */
 4 package generic;
 5 
 6 // 用于测试效果
 7 public class GenericTest02
 8 {
 9     public static void main(String[] args)
10     {
11         Tool tool = new Tool();
12         tool.setObject(new Teacher());
13         // 没用泛型之前,编译器提示必需要进行强制类型转换
14         Teacher teacher = (Teacher) tool.getObject();
15         System.out.println(teacher);
16         
17         Util<Doctor> util = new Util<Doctor>();
18         util.setObject(new Doctor());
19         // 使用泛型之后,不需要进行强转
20         Doctor doctor = util.getObject();
21         System.out.println(doctor);
22     }
23 }
24 
25 // 没有使用泛型
26 class Tool
27 {
28     private Object object;
29 
30     public Object getObject()
31     {
32         return object;
33     }
34 
35     public void setObject(Object object)
36     {
37         this.object = object;
38     }
39 }
40 
41 // 使用泛型,自定义泛型类
42 class Util<Q>
43 {
44     private Q object;
45     
46     public void setObject(Q q)
47     {
48         this.object = q;
49     }
50     public Q getObject()
51     {
52         return object;
53     }
54 }
55 
56 class Doctor
57 {
58 
59 }
60 
61 class Teacher
62 {
63 
64 }
自定义泛型类

方法上定义泛型:

 1 /**
 2  * 方法上定义泛型
 3  */
 4 package generic;
 5 
 6 // 用于测试效果
 7 public class GenericTest03
 8 {
 9     public static void main(String[] args)
10     {
11         Utils ut = new Utils();
12         // 可以打印字符串
13         ut.show("qwe");
14         // 可以打印int类型
15         ut.show(12);
16     }
17 }
18 
19 // 方法上定义泛型
20 class Utils
21 {
22     // 语法格式必须如下所示
23     public <T> void show(T t)
24     {
25         System.out.println("show:" + t);
26     }
27     
28     // 下面两种书写方式都是错的
29     // public void show(T t)
30     // public <T> void show(String str)
31     
32     public <Q> void print(Q q)
33     {
34         System.out.println("print:" + q);
35     }
36     
37     // 泛型字母可以任意定义,不用区分大小写
38     public <Y> void print2(Y y)
39     {
40         System.out.println("print:" + y);
41     }
42 }
方法上定义泛型

类和方法上都定义泛型:

 1 /**
 2  * 类和方法上都定义泛型
 3  */
 4 package generic;
 5 
 6 // 用于测试效果
 7 public class GenericTest04
 8 {
 9     public static void main(String[] args)
10     {
11         Tools<String> tl = new Tools<String>();
12         // 只能打印String类型
13         tl.show("qwer");
14         // 打印其他类型报错
15         // tl.show(123);
16         
17         // 可以打印String类型
18         tl.print("qwe");
19         // 也可以打印其他类型
20         tl.print(123);
21         
22         // 可以打印String类型
23         tl.print2("qwer");
24         // 也可以打印其他类型
25         tl.print2(123);
26         
27         Tools.display("qwe");
28         Tools.display(123);
29     }
30 }
31 
32 // 类和方法上都定义泛型
33 class Tools<T>
34 {
35     // 这个方法的类型是跟着对象(类型T)走的,Q不起作用
36     public <Q> void show(T t)
37     {
38         System.out.println("show:" + t);
39     }
40     
41     // 这个方法的类型是跟着Q走的
42     public <Q> void print(Q q)
43     {
44         System.out.println("print:" + q);
45     }
46     
47     @SuppressWarnings("hiding")
48     public <T> void print2(T q)
49     {
50         System.out.println("print2:" + q);
51     }
52     
53     // 泛型定义在返回值的前面,修饰符的后面
54     public static <W> void display(W w)
55     {
56         System.out.println("display:" + w);
57     }
58 }
类和方法上都定义泛型

 接口上定义泛型:

 1 /**
 2  * 接口上定义泛型
 3  */
 4 package generic;
 5 
 6 // 用于测试效果
 7 public class GenericTest05
 8 {
 9     public static void main(String[] args)
10     {
11         InterImpl01 ii = new InterImpl01();
12         ii.show("qwe");
13         // ii.show(123);  编译时报错
14         
15         InterImpl02<String> ii2 = new InterImpl02<String>();
16         ii2.show("asd");
17         // ii2.show(123);  编译时报错
18         
19         InterImpl02<Integer> ii3 = new InterImpl02<Integer>();
20         ii3.show(123);
21         // ii3.show("asd");  编译时报错
22     }
23 }
24 
25 // 接口上定义泛型
26 interface Inter<T>
27 {
28     public void show(T t);
29 }
30 
31 // T是具体的数据类型,在实现类后面不需要加上 <String>
32 class InterImpl01 implements Inter<String>
33 {
34     @Override
35     public void show(String t)
36     {
37         System.out.println("show:" + t);
38     }
39 }
40 
41 // T如果不是具体的数据类型的话,实现类和接口后面都要加上<T>
42 class InterImpl02<T> implements Inter<T>
43 {
44     @Override
45     public void show(T t)
46     {
47         System.out.println("show:" + t);
48     }
49 }
接口上定义泛型

泛型的高级特性:

高级特性01:

 1 /**
 2  * 功能:泛型的高级特性01
 3  */
 4 package generic.generic05;
 5 
 6 import java.util.ArrayList;
 7 import java.util.Iterator;
 8 
 9 public class GenericTest01
10 {
11     public static void main(String[] args)
12     {
13         ArrayList<String> al1 = new ArrayList<String>();
14         al1.add("qwe");
15         al1.add("asd");
16         al1.add("zxc");
17         
18         ArrayList<Integer> al2 = new ArrayList<Integer>();
19         al2.add(123);
20         al2.add(456);
21         al2.add(789);
22         
23         // demo(al1);
24         // demo(al2);
25         
26         demo2(al1);
27         // demo2(al2);
28     }
29     
30     // 不清楚是什么类型时候,可以用?代替
31     public static void demo(ArrayList<?> al)
32     {
33         Iterator<?> it = al.iterator();
34         while(it.hasNext())
35         {
36             System.out.println("al:" + it.next());
37             // 以下使用length()是错误的
38             // 因为不知道是什么类型,所以不能使用某一具体类型的特有方法
39             // System.out.println(it.next().length());
40         }
41     }
42     
43     // 也可以换成T,但T代表了某一个具体类型,比如String,不是真让你写一个T在里面,其实是写一个具体类型
44     // 操作方面有一点变化
45     public static <T> void demo2(ArrayList<T> al)
46     {
47         Iterator<T> it = al.iterator();
48         while(it.hasNext())
49         {
50             System.out.println("al:" + it.next());
51             // 使用了某一具体类型之后
52             // 可以用这个具体类型来接收迭代出来的元素,并进行其他具体操作
53             /*T t = it.next();
54             System.out.println("al:" + t);*/
55         }
56     }
57 }
高级特性01

高级特性02:

  1 /**
  2  * 功能:泛型的高级特性02
  3  */
  4 package generic;
  5 
  6 import java.util.ArrayList;
  7 import java.util.Iterator;
  8 
  9 public class GenericTest07
 10 {
 11     public static void main(String[] args)
 12     {
 13         ArrayList<Person> al = new ArrayList<Person>();
 14         al.add(new Person("qwe"));
 15         al.add(new Person("asd"));
 16         al.add(new Person("zxc"));
 17         
 18         ArrayList<Worker> al2 = new ArrayList<Worker>();
 19         al2.add(new Worker("qwe"));
 20         al2.add(new Worker("asd"));
 21         al2.add(new Worker("zxc"));
 22         
 23         ArrayList<Student> al3 = new ArrayList<Student>();
 24         al3.add(new Student("qwe"));
 25         al3.add(new Student("asd"));
 26         al3.add(new Student("zxc"));
 27         
 28         // 正确
 29         demo(al);
 30         // 以下两种写法错误,是不允许的,左右不匹配
 31         // ArrayList<Person> al2 = new ArrayList<Student>();
 32         // ArrayList<Student> al2 = new ArrayList<Person>();
 33         // demo(al2);  // 错误,只能打印 ArrayList<Person> 类型数据
 34         // demo(al3);  // 错误,只能打印 ArrayList<Person> 类型数据
 35         
 36         demo2(al);
 37         demo2(al2);
 38         demo2(al3);
 39         
 40         demo3(al2);
 41         demo3(al);
 42         // Student类不是Person类的子类,所以下面写法错误
 43         // demo3(al3);
 44         
 45         demo4(al);
 46         demo4(al2);
 47         // Student类不是Worker类的父类,所以下面写法错误
 48         // demo4(al3);
 49     }
 50     
 51     // 打印出特定类型
 52     public static void demo(ArrayList<Person> al)
 53     {
 54         Iterator<Person> it = al.iterator();
 55         while(it.hasNext())
 56         {
 57             Person p = it.next();
 58             System.out.println("name:" + p.getName());
 59         }
 60     }
 61     
 62     // 打印出所有类型
 63     public static void demo2(ArrayList<?> al)
 64     {
 65         Iterator<?> it = al.iterator();
 66         while(it.hasNext())
 67         {
 68             System.out.println(it.next());
 69         }
 70     }
 71     
 72     // 打印出指定的范围类型:泛型限定
 73     // 只打印Person和它的子类
 74     public static void demo3(ArrayList<? extends Person> al)
 75     {
 76         Iterator<? extends Person> it = al.iterator();
 77         while(it.hasNext())
 78         {
 79             // 可以调用具体方法
 80             System.out.println(it.next().getName());
 81         }
 82     }
 83     
 84     // 打印出指定的范围类型:泛型限定
 85     // 只打印Worker和它的父类(是Worker类的基类)
 86     public static void demo4(ArrayList<? super Worker> al)
 87     {
 88         Iterator<? super Worker> it = al.iterator();
 89         while(it.hasNext())
 90         {
 91             System.out.println(it.next());
 92         }
 93     }
 94 }
 95 
 96 class Person
 97 {
 98     private String name;
 99     
100     public Person(String name)
101     {
102         this.name = name;
103     }
104     
105     public String getName()
106     {
107         return name;
108     }
109     public void setName(String name)
110     {
111         this.name = name;
112     }
113 }
114 
115 class Student
116 {
117     private String name;
118     
119     public Student(String name)
120     {
121         this.name = name;
122     }
123     
124     public String getName()
125     {
126         return name;
127     }
128     public void setName(String name)
129     {
130         this.name = name;
131     }
132 }
133 
134 class Worker extends Person
135 {
136     public Worker(String name)
137     {
138         super(name);
139     }
140 }
高级特性02

高级特性03:

  1 /**
  2  * 未使用高级特性之前
  3  */
  4 package generic;
  5 
  6 import java.util.Comparator;
  7 import java.util.Iterator;
  8 import java.util.TreeSet;
  9 
 10 public class GenericTest08_1
 11 {
 12     public static void main(String[] args)
 13     {
 14         // 使用Studnet类的构造器
 15         TreeSet<Student1> tr = new TreeSet<Student1>(new StuComparator());
 16         tr.add(new Student1("stu4"));
 17         tr.add(new Student1("stu2"));
 18         tr.add(new Student1("stu3"));
 19         
 20         Iterator<Student1> it = tr.iterator();
 21         while(it.hasNext())
 22         {
 23             System.out.println("tr:" + it.next().getName());
 24         }
 25         
 26         // 使用Worker类的构造器
 27         TreeSet<Worker1> tr2 = new TreeSet<Worker1>(new WorComparator());
 28         tr2.add(new Worker1("wor1"));
 29         tr2.add(new Worker1("wor5"));
 30         tr2.add(new Worker1("wor3"));
 31         
 32         Iterator<Worker1> it2 = tr2.iterator();
 33         while(it2.hasNext())
 34         {
 35             System.out.println("tr:" + it2.next().getName());
 36         }
 37     }
 38 }
 39 
 40 class MyComparator implements Comparator<Person1>
 41 {
 42     @Override
 43     public int compare(Person1 o1, Person1 o2)
 44     {
 45         return o1.getName().compareTo(o2.getName());
 46     }
 47 }
 48 
 49 // Student类的比较器,分开写很麻烦
 50 class StuComparator implements Comparator<Student1>
 51 {
 52     @Override
 53     public int compare(Student1 o1, Student1 o2)
 54     {
 55         return o1.getName().compareTo(o2.getName());
 56     }
 57 }
 58 
 59 // Worker类的比较器,分开写很麻烦
 60 class WorComparator implements Comparator<Worker1>
 61 {
 62     @Override
 63     public int compare(Worker1 o1, Worker1 o2)
 64     {
 65         return o1.getName().compareTo(o2.getName());
 66     }
 67 }
 68 
 69 class Person1
 70 {
 71     private String name;
 72     
 73     public Person1(String name)
 74     {
 75         this.name = name;
 76     }
 77 
 78     public String getName()
 79     {
 80         return name;
 81     }
 82     public void setName(String name)
 83     {
 84         this.name = name;
 85     }
 86 }
 87 
 88 class Student1 extends Person1
 89 {
 90     // private String name;
 91     public Student1(String name)
 92     {
 93         super(name);
 94     }
 95 }
 96 
 97 class Worker1 extends Person1
 98 {
 99     public Worker1(String name)
100     {
101         super(name);
102     }
103 }
未使用高级特性之前
 1 /**
 2  * 使用高级特性之后
 3  */
 4 package generic;
 5 
 6 import java.util.Comparator;
 7 import java.util.Iterator;
 8 import java.util.TreeSet;
 9 
10 public class GenericTest08_2
11 {
12     public static void main(String[] args)
13     {
14         // 使用通用的比较器(父类的比较器)
15         TreeSet<Student2> tr = new TreeSet<Student2>(new MyComparator2());
16         tr.add(new Student2("stu4"));
17         tr.add(new Student2("stu2"));
18         tr.add(new Student2("stu3"));
19         
20         Iterator<Student2> it = tr.iterator();
21         while(it.hasNext())
22         {
23             System.out.println("tr:" + it.next().getName());
24         }
25         
26         // 使用通用的比较器(父类的比较器)
27         TreeSet<Worker2> tr2 = new TreeSet<Worker2>(new MyComparator2());
28         tr2.add(new Worker2("wor1"));
29         tr2.add(new Worker2("wor5"));
30         tr2.add(new Worker2("wor3"));
31         
32         Iterator<Worker2> it2 = tr2.iterator();
33         while(it2.hasNext())
34         {
35             System.out.println("tr:" + it2.next().getName());
36         }
37     }
38 }
39 
40 class MyComparator2 implements Comparator<Person2>
41 {
42     @Override
43     public int compare(Person2 o1, Person2 o2)
44     {
45         return o1.getName().compareTo(o2.getName());
46     }
47 }
48 
49 class Person2
50 {
51     private String name;
52     
53     public Person2(String name)
54     {
55         this.name = name;
56     }
57 
58     public String getName()
59     {
60         return name;
61     }
62     public void setName(String name)
63     {
64         this.name = name;
65     }
66 }
67 
68 class Student2 extends Person2
69 {
70     // private String name;
71     public Student2(String name)
72     {
73         super(name);
74     }
75 }
76 
77 class Worker2 extends Person2
78 {
79     public Worker2(String name)
80     {
81         super(name);
82     }
83 }
使用高级特性之后
原文地址:https://www.cnblogs.com/kehuaihan/p/8470899.html