配色: 字号:
JAVA之旅(二十一)
2016-10-07 | 阅:  转:  |  分享 
  
JAVA之旅(二十一)

一.泛型的概述



什么是泛型,我们可以用一个很典型的例子来说明

packagecom.lgl.hellojava;



importjava.util.ArrayList;

importjava.util.Iterator;



//公共的类类名

publicclassHelloJJAVA{

publicstaticvoidmain(String[]args){

/

泛型

/

ArrayListal=newArrayList();

al.add("hello1");

al.add("hello02");

al.add("hello0300");

al.add("hello084");

//添加int

al.add(5);

Iteratoriterator=al.iterator();

while(iterator.hasNext()){

Strings=(String)iterator.next();

//打印长度

sop(s.length());

}

}



//输出

publicstaticvoidsop(Objectobj){

System.out.println(obj);



}

}

这里,我们用一个arraylist存储的数据有String也有int,输出的结果



不会发现,他报的就是类型的异常,我们要怎么去解决?这里就牵扯出泛型来了

泛型:JDK1.5版本之后出现的新特性,用于解决安全问题,是一个安全机制;

我们要怎么使用?

ArrayListal=newArrayList();



我定义了一个容器,容器的参数是String类型,规范了数据类型,就不能存其他的数据了,安全性提高了!

好处:讲运行时期出现的问题转移到了编译时期,方便程序员解决问题,让运行时期问题减少,安全

二.泛型的使用



泛型的格式:通过<>来定义要操作的引用数据类型,在使用JAVA提供的对象时,什么时候写泛型呢,通常在集合框架中很常见,只要见到<>就是定义泛型!



其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型,作为参数,传递到<>一样,我们来个小例子

packagecom.lgl.hellojava;



importjava.util.Comparator;

importjava.util.Iterator;

importjava.util.TreeSet;



//公共的类类名

publicclassHelloJJAVA{

publicstaticvoidmain(String[]args){

TreeSettr=newTreeSet(newLenComp());

tr.add("hello01");

tr.add("hello012");

tr.add("hello013");

tr.add("hello014");



Iteratoriterator=tr.iterator();

while(iterator.hasNext()){

Stringstring=iterator.next();

sop(string);

}

}



//输出

publicstaticvoidsop(Objectobj){

System.out.println(obj);



}

}



//比较器

classLenCompimplementsComparator{



@Override

publicintcompare(Stringo1,Stringo2){

Strings1=o1;

intnum=newInteger(o1.length()).compareTo(newInteger(o2.length()));

if(num==0){

returno1.compareTo(o2);

}

returnnum;

}



}



你可以仔细的看看里面是怎么用泛型的,就是一些小技巧

三.泛型类



这是我们优化代码比较常见的一种方式,我们可以看这块代码

packagecom.lgl.hellojava;



//公共的类类名

publicclassHelloJJAVA{

publicstaticvoidmain(String[]args){

Toolt=newTool();

t.setW(newWorker());

t.getW();

}



//输出

publicstaticvoidsop(Objectobj){

System.out.println(obj);



}

}

//操作工人的工具类

classTool{

privateWorkerw;



publicWorkergetW(){

returnw;

}



publicvoidsetW(Workerw){

this.w=w;

}



}



classWorker{



}





这里,有一个工人的类,我们定义一个工具类去操作,对吧,这个逻辑就是这么的简单,但是你回发现,如果我在定义一个学生的类,就又得需要一个学生的工具类了,我们为什么不去合并这个工具类,抽调共有的方法呢?你会说可以用Object?

//操作工人的工具类

classTool{

privateObjectobj;



publicObjectgetObj(){

returnobj;

}



publicvoidsetObj(Objectobj){

this.obj=obj;

}



}



这样的话,你如果传递的话,还是要定义床底类型,不然会报类型异常的,我们泛型的用法

classUtils{



privateTt;



publicTgetT(){

returnt;

}



publicvoidsetT(Tt){

this.t=t;

}

}



由你来指定传递进来的参数,这样就可以为所欲为了

什么时候定义泛型类

当类中要操作的引用数据类型不确定的时候,早起定义Object来完成扩展,现在定义泛型来完成扩展

四.泛型方法



泛型除了定义在类中,还是可以定义在方法上的,我们来看一下

packagecom.lgl.hellojava;



//公共的类类名

publicclassHelloJJAVA{

publicstaticvoidmain(String[]args){

Demod=newDemo();

d.show("hh");

d.print("aa");

}

}



classDemo{

publicvoidshow(Tt){

System.out.println("show:"+t);

}



publicvoidprint(Tt){

System.out.println("print:"+t);

}

}



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

为了让不同的方法可以操作不同的类型,而且类型不确定,那么可以将泛型定义在方法上

仔细看

classDemo{

publicvoidshow(Tt){



}

publicvoidprint(Tt){



}

}



这样就可以传递泛型参数了

五.静态泛型方法



这个倒不是什么大知识点,就是注意一下,泛型方法不能使用静态的,也可以说静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上,就可以了



classDemo{

publicvoidshow(Tt){



}



publicvoidprint(Tt){



}



publicstaticvoidmethod(Tt){



}

}



要放在static后面哦!

六.泛型接口



你类和方法都有了,怎么能少得了接口呢?

packagecom.lgl.hellojava;





//公共的类类名

publicclassHelloJJAVA{

publicstaticvoidmain(String[]args){

InterImpli=newInterImpl();

i.shwww.sm136.comow(55);

}

}



classInterImplimplementsInter{



@Override

publicvoidshow(Tt){

System.out.println("show:"+t);

}



}



interfaceInter{

voidshow(Tt);

}



结构也差不多,传参数就行,但是这种情况是不多见的

七.泛型限定



我们来玩玩泛型的高级用法,go

先从例子切入正题

packagecom.lgl.hellojava;



importjava.util.ArrayList;

importjava.util.Iterator;



//公共的类类名

publicclassHelloJJAVA{

publicstaticvoidmain(String[]args){

ArrayListal=newArrayList();



al.add("hello01");

al.add("hello02");

al.add("hello03");

al.add("hello04");



ArrayListall=newArrayList();

all.add(9);

all.add(596);

all.add(98);

all.add(97);



printColl(all);

}

//内容不明确

publicstaticvoidprintColl(ArrayListals){

Iteratoriterator=als.iterator();

while(iterator.hasNext()){

System.out.println(iterator.next());

}

}

}



问号是占位符,上面的逻辑就是我们有两个arrayList,但是我们需要公用一个方法,内容不明确,所以用问号占位,其实实现的方式还有很多种,还有一种需求使用不到?的,因为?是打印任何的数据,但是我只需要打印限定的几种类型,这个时候该怎么做?

packagecom.lgl.hellojava;



importjava.util.ArrayList;

importjava.util.Iterator;



//公共的类类名

publicclassHelloJJAVA{



publicstaticvoidmain(String[]args){

ArrayListal=newArrayList();

al.add(newPerson("zhangsan"));

al.add(newPerson("lisi"));

al.add(newPerson("wangwu"));



ArrayListal1=newArrayList();

al1.add(newStudent("zhangsan--1"));

al1.add(newStudent("lisi--2"));

al1.add(newStudent("wangwu--3"));



//ArrayList

printColl(al1);

}



//内容不明确

publicstaticvoidprintColl(ArrayListals){

Iteratoriterator=als.iterator();

while(iterator.hawww.shanxiwang.netsNext()){

System.out.println(iterator.next().getName());

}

}

}



classPerson{

privateStringname;



publicPerson(Stringname){

this.name=name;

}



publicStringgetName(){

returnname;

}



publicvoidsetName(Stringname){

this.name=name;

}

}



classStudentextendsPerson{



publicStudent(Stringname){

super(name);

}

}



这里,就能打印出学生和人类,而不打印其他类型的参数了,这就叫泛型限定

?叫通配符,也可以理解为占位符

泛型的限定?extendsE:E类型和E的子类型。这叫上限

?superE:可以接受E类型和E的父类,这叫下限

下限我就不演示了,有机会的同学可以自己试试看,还是挺好玩的

献花(0)
+1
(本文系网络学习天...首藏)