黑马程序员——泛型
来源:互联网 发布:python 获取当前日期 编辑:程序博客网 时间:2024/05/16 07:01
一、概述
1、JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。
2、格式:
通过<>来定义要操作的引用数据类型
3、JDK1.5的集合类希望在定义集合时,明确表明你要向集合中装入那种类型的数据,无法加入指定类型以外的数据。如:ArrayList<String> //定义要存入集合中的元素指定为String类型
如: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、创建泛型类对象
2、实现泛型类接口Utils<String> ut = new Utils<String>();
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);}}
- 黑马程序员—泛型
- 黑马程序员—泛型
- 黑马程序员—泛型
- 黑马程序员—泛型
- 黑马程序员—泛型
- 黑马程序员—泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 黑马程序员——泛型
- 第6章深入使用Hibernate 6.3 Hibernate的批量处理
- SQL SERVER打开.mdf和.ldf文件
- 滚动柱形图的画法
- 认识与入门 Markdown
- spring4+quartz2.2.1
- 黑马程序员——泛型
- sklearn中决策树实现
- 死锁小结
- Android面试题总结(三)
- document.body 和 docuement.documentElement
- 安卓开发环境安装--菜鸟之路(一)
- python 中 exec、 eval、 execfile 和 compile 用法
- 关于面试经常被问到的socket的TIME_WAIT状态的原因及解决办法和避免的办法
- CSS 绝对定位属性absolute用法初探