集合框架(泛型)

来源:互联网 发布:360浏览器mac版下载 编辑:程序博客网 时间:2024/05/20 03:45

泛型总说:

泛型出现的必要性:

数组在定义时就已经确定了里面存储的数据类型如:

<span style="font-size:18px;"> int[ ] num = {1,5,6,7};  String[ ] str = {"abc","fdg","uio"};</span>

但是对于集合,他可以接受任何引用数据类型的对象,泛型之前的容器需要接受参数的大都是Object类型的,所以从集合框架中取出的数据还是Object类型的,还需要对其进行向下转型,还有因为他可以存储任何类型,你既可以存入Person对象,也可以存入Car类型,什么都可以往里面装,而且编译器还不能检测到语法错误。等到运行是才出现问题。程序的安全性不好。所以泛型来了。
泛型的好处:
泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。
好处
1.将运行时期出现问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时问题减少,安全。
2,避免了强制转换麻烦。
泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,
只要见到<>就要定义泛型。
其实<> 就是用来接收类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

示例:

<span style="font-size:18px;">class GenericDemo {public static void main(String[] args) {ArrayList<String> al = new ArrayList<String>();al.add("abc01");al.add("abc0991");al.add("abc014");for (Iterator<String> it = al.iterator(); it.hasNext();) {String s = it.next();System.out.println(s + ":" + s.length());}}}</span>

泛型类:

定义的泛型在整个类中有效。如果被方法使用,那么如果泛型类的对象已经明确操作的具体类型后,所有要操作的类型就已经固定了。
什么时候使用泛型类:
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。现在定义泛型来完成扩展。

<span style="font-size:18px;">/*class Tool {private Worker w;public void setWorker(Worker w) {this.w = w;}public Worker getWorker() {return w;}}*/class Worker {// do something}class Student {// do something}// 泛型前做法。class Tool {private Object obj;public void setObject(Object obj) {this.obj = obj;}public Object getObject() {return obj;}}// 泛型类。class Utils<QQ> {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<Worker> u = new Utils<Worker>();u.setObject(new Student());Worker w = u.getObject();;/* * Tool t = new Tool(); t.setObject(new Student()); Worker w = * (Worker)t.getObject(); */}}</span>

泛型方法:

    为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。
特殊之处:静态方法不可以访问类上定义的泛型。(因为类上定义的泛型在创建对象是才确定具体的类型)
   如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
泛型方法与泛型类比较示例代码:
说明:泛型类和泛型方法没有绝对的界限,而且可以混合使用,如果要操作某一特定类型T的数据,
就可以定义为泛型类,所有方法也可以定义为T类型,就像集合中的那样。
而泛型方法更具灵活性,可以操作所传入的任意类型。
<span style="font-size:18px;">class Demo<T> {// 操作的类型为类上定义的<T>public void show(T t) {System.out.println("show:" + t);}// 与类上的泛型无关,可以接受任何类型public <Q> void print(Q q) {System.out.println("print:" + q);}// 静态方法不能用类上定义的泛型,只能定义在方法上public static <W> void method(W t) {System.out.println("method:" + t);}}class GenericDemo4 {public static void main(String[] args) {Demo<String> d = new Demo<String>();d.show("haha");// d.show(4);d.print(5);d.print("hehe");Demo.method("hahahahha");  /*  Demo d = new Demo();  d.show("haha");  d.show(new Integer(4));  d.print("heihei");  */  /*  //只有对象建立了才能确定数据类型,所以静态方法不能用类上定义的泛型  Demo<Integer> d = new Demo<Integer>();  d.show(new Integer(4));  d.print("hah");  Demo<String> d1 = new Demo<String>();  d1.print("haha");  d1.show(5);  */}}</span>

泛型接口:

<span style="font-size:18px;">/泛型定义在接口上。  interface Inter<T>{      void show(T t);  }    /*将接口实现定义为String,只能操作String类型数据 class InterImpl implements Inter<String>{     public void show(String t){         System.out.println("show :"+t);     } }  */    //将接口实现类定义为不确定的类型,操作传入的类型  class InterImpl<T> implements Inter<T>{      public void show(T t){          System.out.println("show :"+t);      }  }    class GenericDemo5 {      public static void main(String[] args) {            InterImpl<Integer> i = new InterImpl<Integer>();          i.show(4);          //InterImpl i = new InterImpl();          //i.show("haha");      }  }  </span>

泛型的高级应用:

? 通配符。也可以理解为占位符。
泛型的限定;
? extends E: 可以接收E类型或者E的子类型。上限。
? super E: 可以接收E类型或者E的父类型。下限
注意:
在使用下限的时候,一般在传入的为父类,因为这样,只要是子类就可以接收,提高了扩展性,但是只能用父类的方法。
示例一:

<span style="font-size:18px;">class Person4 {private String name;Person4(String name) {this.name = name;}public String getName() {return name;}}class Student4 extends Person4 {private String name;Student4(String name) {super(name);}// 这里定义之后打印的是null,因为覆盖了父类的getName方法,但是初始化是到父类初始化,// 所以使用的不是同一个name,本类中的name并没有赋值public String getName() {return name;}}class GenericDemo6 {public static void main(String[] args) {/* * ArrayList<String> al = new ArrayList<String>(); *  * al.add("abc1"); al.add("abc2"); al.add("abc3"); *  * printColl(al); *  * ArrayList<Integer> al1 = new ArrayList<Integer>(); al1.add(4); * al1.add(7); al1.add(1); *  * printColl(al1); */ArrayList<Person4> al = new ArrayList<Person4>();al.add(new Person4("abc1"));al.add(new Person4("abc2"));al.add(new Person4("abc3"));printColl(al);ArrayList<Student4> al1 = new ArrayList<Student4>();al1.add(new Student4("abc--1"));al1.add(new Student4("abc--2"));al1.add(new Student4("abc--3"));printColl(al1); // ArrayList<? extends Person> al = new// ArrayList<Student>();error}public static void printColl(Collection<? extends Person4> al)// 接收Person及Person的子类型,多态{Iterator<? extends Person4> it = al.iterator();while (it.hasNext()) {System.out.println(it.next().getName());}}/* * 如果明确定义为<T>类型,可以接收并操作T类型,而<?>因为没确定类型, 所以不可以使用类型的特有方法 public static void * printColl(ArrayList<?> al){ //ArrayList al = new * ArrayList<Integer>();error *  * Iterator<?> it = al.iterator(); *  * while(it.hasNext()) { System.out.println(it.next().toString()); } } */}</span>
示例二:

<span style="font-size:18px;">class Person4 {private String name;Person4(String name) {this.name = name;}public String getName() {return name;}}class Student4 extends Person4 {private String name;Student4(String name) {super(name);}// 这里定义之后打印的是null,因为覆盖了父类的getName方法,但是初始化是到父类初始化,// 所以使用的不是同一个name,本类中的name并没有赋值public String getName() {return name;}}class GenericDemo6 {public static void main(String[] args) {/* * ArrayList<String> al = new ArrayList<String>(); *  * al.add("abc1"); al.add("abc2"); al.add("abc3"); *  * printColl(al); *  * ArrayList<Integer> al1 = new ArrayList<Integer>(); al1.add(4); * al1.add(7); al1.add(1); *  * printColl(al1); */ArrayList<Person4> al = new ArrayList<Person4>();al.add(new Person4("abc1"));al.add(new Person4("abc2"));al.add(new Person4("abc3"));printColl(al);ArrayList<Student4> al1 = new ArrayList<Student4>();al1.add(new Student4("abc--1"));al1.add(new Student4("abc--2"));al1.add(new Student4("abc--3"));printColl(al1); // ArrayList<? extends Person> al = new// ArrayList<Student>();error}public static void printColl(Collection<? extends Person4> al)// 接收Person及Person的子类型,多态{Iterator<? extends Person4> it = al.iterator();while (it.hasNext()) {System.out.println(it.next().getName());}}/* * 如果明确定义为<T>类型,可以接收并操作T类型,而<?>因为没确定类型, 所以不可以使用类型的特有方法 public static void * printColl(ArrayList<?> al){ //ArrayList al = new * ArrayList<Integer>();error *  * Iterator<?> it = al.iterator(); *  * while(it.hasNext()) { System.out.println(it.next().toString()); } } */}</span>




0 0