黑马程序员——泛型

来源:互联网 发布:python 获取当前日期 编辑:程序博客网 时间:2024/05/16 07:01
------- android培训、java培训、期待与您交流! ----------


一、概述

1、JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。

2、格式:

通过<>来定义要操作的引用数据类型

如:ArrayList<String>  //定义要存入集合中的元素指定为String类型

3、JDK1.5的集合类希望在定义集合时,明确表明你要向集合中装入那种类型的数据,无法加入指定类型以外的数据。

如:ArrayList<String> al = new ArrayList<String>();定义泛型后,al 只能添加 String 对象。

4、没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用泛型集合,可以将一个集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全;并且当从集合获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制类型转换,这样更方便。泛型就是把原来的类名进行了延长!在JDK 1.5中,你还可以按原来的方式将各种不同类型的数据装到一个集合中,但编译器会报告unchecked警告。

5、好处

a、将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时期问题减少、安全。

b、避免了强制转换的麻烦。如在实现某一个接口时,指定传入接口方法的实参的类型的话,在复写该接口方法时就可以直接使用指定类型,而不需要强制转换。

泛型的基本使用

在使用java提供的对象时,什么时候写泛型呢?

通常在集合框架中很常见,只要见到<>就要定义泛型。

其实<> 就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

例:

class GenericDemo {public static void main(String[] args) {ArrayList<String> al = new ArrayList<String>();al.add("abc01");al.add("abc0991");al.add("abc014");//al.add(4);  这时添加Sring之外的类型编译会报错//al.add(new Integer(4));//al添加泛型,所以Iterator也需要添加泛型,否则会编译出错Iterator<String> it = al.iterator();while(it.hasNext()){String s = it.next();System.out.println(s+":"+s.length());}}}<strong></strong>


二、泛型与类

定义类时:

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候。早期定义Object来完成扩展,JDK1.5后定义泛型来完成扩展。

泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所以要操作的类型就已经固定了。

格式:

class 类名<XX>

{public XX ;...........}

在类名后面用 <XX> ,其中XX表示未确定的类型。在类中直接当XX为一种类型使用。

例如,定义一个泛型类。

//这个类中QQ为不确定的类型,须在使用的时候传入,传入后类中的QQ类型就确定了class Utils<QQ>{private QQ q;public void setObject(QQ q){this.q = q;}public QQ getObject(){return q;}}


使用类时:

1、创建泛型类对象

Utils<String> ut = new Utils<String>();

2、实现泛型类接口

class TestClass implements Comparator<String>

{..............}

也可以“拖延到”在被使用时才确定类型

class TestClass<QQ> implements Comparator<QQ>

{..............}


三、泛型与方法

定义方法时:

当方法需要的使用泛型时,可以引用类定义的泛型。

但是,为了让不同方法可以操作不同类型,而且类型还不确定。那么也可以在方法上定义泛型。

格式:

public <Q> void print(Q q)

泛型须定义在修饰符后面,返回值类型的前面。

需注意,静态方法无法引用类定义的泛型(类似静态方法无法引用非静态成员)。如果需要使用泛型,可以将泛型定义在该方法上。

例如:

class Demo<T>{public  void show(T t){System.out.println("show:"+t);}//普通成员方法,Q为该方法特有,与类无关public <Q> void print(Q q){Q q2 = q;//还可以对该类型进行操作System.out.println("print:"+q+""+q2);}//静态方法,无法引用类中的 T 。public  static <W> void method(W t){System.out.println("method:"+t);}}

使用方法时:

如下例:

public static void main(String[] args) {Demo <String> d = new Demo<String>();//show()只能接收String类型变量d.show("haha");//print()方法接收的类型不受类中定义的类型限制d.print(5);d.print("hehe");Demo.method("hahahahha");}


四、泛型的限定

?通配符。也可以理解为占位符。当传入的类型不确定时使用。如:

ArrayList<?> arrayList1 = new ArrayList<String>();

ArrayList<?> arrayList2 = new ArrayList<Integer>();

上面两个都可以编译通过,但是arrayList1.add(new Integer(4));、arrayList2.add("abc");会出错。

"?"虽然 提高了程序的扩展性,但是无法使用类型的特有方法。若需要使用特有方法,可使用泛型限定

泛型的限定:
? extends E: 可以接收E类型或者E的子类型。上限。
? super E:     可以接收E类型或者E的父类型。下限。

泛型的限定与通配符的使用类似,只是泛型的限定拥有上限或者下限。

如:

ArrayList<? extends Object> al = new ArrayList<String>();

ArrayList<? super String> al = new ArrayList <Object>();

还可以在定义方法的时候使用

定义:

public void printColl(Collection<? extends Number> al)

{...............}

调用:

printColl(new ArrayList<Integer>());

上限例子:

import java.util.*;class  GenericDemo6{public static void main(String[] args) {ArrayList<Person> al = new ArrayList<Person>();al.add(new Person("abc1"));al.add(new Person("abc2"));al.add(new Person("abc3"));printColl(al);ArrayList<Student> al1 = new ArrayList<Student>();al1.add(new Student("abc--1"));al1.add(new Student("abc--2"));al1.add(new Student("abc--3"));printColl(al1); ArrayList<Student> al1 = new ArrayList<Student>();al1.add(new Student("abc--1"));al1.add(new Student("abc--2"));al1.add(new Student("abc--3"));printColl(al1); }//该方法可以接受Person、Student、Worker三个类。同时也能使用他们的共性方法public static void printColl(Collection<? extends Person> al){Iterator<? extends Person> it = al.iterator();while(it.hasNext()){//可用使用三个类型的公用方法getName()。System.out.println(it.next().getName());}}}/*定义三个类  Person   |--Student   |--Worker*/class Person{private String name;Person(String name){this.name = name;}public String getName(){return name;}}class Student extends Person{Student(String name){super(name);}}class Worker extends Person{Worker(String name){super(name);}}







0 0
原创粉丝点击