Java集合框架篇-49-泛型(Generic)基本了解和使用

xiaoxiao2021-02-28  48

      接下来这篇,我们学习泛型。前面文章,我们在创建集合对象的时候,如果不添加注解,IDE上就会有黄色的波浪线,学习了这篇之后,我们就会对泛型有一个基本了解和使用。

 

1.什么是泛型

打开API文档,搜索Collection,观察下面图片中红圈的尖括号就是泛型。

      那么这个尖括号(泛型)是用来干嘛的呢?里面是表示参数类型是引用数据类型,例如String,和我们前面使用的Student,Person都是引用数据类型。主要起的作用是限定参数类型是某一个引用数据类型。如果加上了引用数据类型,就是该对象只能存储这个类型的引用数据类或者该类的子类对象。例如如何一个集合后面尖括号里面是Student,那么这个集合只能存储我们前面定义的自定义对象,即学生类。

2.泛型的好处

好处有两个:

1)提高了安全性(将运行期错误转换到编译区)

2)省去强制转换的麻烦

下面我们先来看看,不加泛型限定的集合,有什么麻烦出现。

先把需要用到的Student.java的代码贴出来。

package collection; public class Student { private String name; private int age; public Student() { super(); } public Student(String name, intage) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(intage) { this.age = age; } @Override public String toString() { return "Student [name="+ name+ ", age="+ age+ "]"; } }

      写一个没有限制参数类型的集合,在遍历代码块中,假如我们只想获取学生的姓名这个字段,结果会发现报错。

package generic; import java.util.ArrayList; import java.util.Iterator; import collection.Student; public class Demo1_Generic { public static void main(String[] args) { ArrayListlist= newArrayList(); list.add(100); list.add(true); list.add(new Student("张三",23)); Iteratorit = list.iterator(); while(it.hasNext()) { Studentp = (Student)it.next(); System.out.println(p.getName()); } } }

运行异常:

Exception in thread "main" java.lang.ClassCastException:java.lang.Integer cannot be cast to collection.Student atgeneric.Demo1_Generic.main(Demo1_Generic.java:20)

      我们先在API 文档中搜索ClassCastException这个类,看看什么意思。可以看到这样的解释:当试图将对象强制转换为不是实例的子类时,抛出该异常。例如,我们想把一个猫类对象强制转换成狗类对象就会出现这个异常。

      所以,上面代码,在集合没有限定引用类型,在编译代码的时候就通过没有报错,但是运行就报错。原因就是,我们集合中存储了Integer和Boolean以及Student三种类型的引用数据类型,但是后面遍历,我们写了强制转换代码,这里就会把Integer和Boolean强制转换成Student对象,就会发生强制转换异常。

     下面写一个带上泛型的集合,例如我们下面限定集合内引用数据类型只能是Student对象。

package generic; import java.util.ArrayList; import java.util.Iterator; import collection.Student; public class Demo1_Generic { public static void main(String[] args) { ArrayList<Student>list= newArrayList<Student>(); //list.add(100); //list.add(true); list.add(new Student("张三",23)); Iterator<Student>it = list.iterator(); while(it.hasNext()) { Students = it.next(); //这里不用强制转换了 System.out.println(s.getName()); } } }

      上面集合类型限制了是Student,如果添加Integer或者Boolean就会编译报错,体现了提高安全性的特点,下面迭代器遍历不需要添加强转。

 

3.泛型特点和注意事项

1)尖括号里必须是引用数据类型

2)前后泛型限制类型必须一致,后面可以省略不写

3)限制类型最好不用Object

ArrayList<Student> list = newArrayList<Object>(); //前后不一致,编译出错 ArrayList<Student>list2= newArrayList(); //后面可以不写 ArrayList<Object>list3= newArrayList(); //最好不用Obect类型,相当于没有限制

4.用泛型来写字符串和自定义集合练习

1)字符串版本

package generic; import java.util.ArrayList; import java.util.Iterator; import collection.Student; public class Demo1_Generic { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); Iterator<String> it = list.iterator(); //集合是什么类型,迭代器保持一样 while(it.hasNext()) { System.out.println(it.next()); } } }

输出:

a b c d

2)自定义版本

     

package generic; import java.util.ArrayList; import java.util.Iterator; import collection.Student; public class Demo1_Generic { public static void main(String[] args) { ArrayList<Student> list = new ArrayList<Student>(); list.add(new Student("张三",23)); list.add(new Student("李四",24)); list.add(new Student("王五",25)); Iterator<Student> it = list.iterator(); //集合是什么类型,迭代器保持一样 while(it.hasNext()) { Student s = it.next(); System.out.println(s.getName() + "..." +s.getAge()); } } }

运行输出:

张三...23李四...24王五...25

 

转载请注明原文地址: https://www.6miu.com/read-2626738.html

最新回复(0)