JAVA高新技术——泛型总结

来源:互联网 发布:网络抓包有什么用 编辑:程序博客网 时间:2024/06/06 23:17

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

一、初步了解泛型,及详解

泛型定义:

    泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写 体验泛型

代码时定义一些可变部分,那些部分在使用前必须作出指明。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。

JAVA  中实行泛型的好处?

泛型的主要好处就是让编译器保留参数的类型信息,执行类型检查,执行类型转换操作,编译器保证了这些类型转换的绝对无误。相对于依赖程序员来记住对象类型、执行类型转换——这会导致程序运行时的失败,很难调试和解决,而编译器能够帮助程序员在编译时强制进行大量的类型检查,发现其中的错误。

二、 java泛型实例

 1.1  简单的泛型

1)实体类Point

ackage fanXing5_6;

/*JDK1.5 之后出现了新的技术--泛型,此技术的最大特点是类中的属性的类型可以有外部

*决定,

 * 而且在声明类的室友应该采用如下的形式:

 * */

publicclass Point<T> {//表示坐标

private Tx;//x属性的类型由外部决定

private Ty;//y属性的类型由外部决定

public T getX(){

    returnx;

}

publicvoid setX(T x){

    this.x=x;

}

public T getY(){

    returny;

}

publicvoid setY(T y){

    this.y=y;

}

}

2)测试类1-GenDemo05

  package fanXing5_6;

/*程序加入的泛型操作之后,可以发现一切的操作类型此时不再由程序固定设置,而是由实例化对象的时候在

 * 外部进行了指定。

 * */

publicclass GenDemo05 {

publicstaticvoid main(String[] args) {

    Point<Integer>p=new Point<Integer>();

    p.setX(11);

    p.setY(20);

    int x=p.getX();

    int y=p.getY();

    System.out.println("X的坐标是:"+x);

    System.out.println("y的坐标是:"+y);

    }

    }

 

3)测试类2-GenDemo06

 package fanXing5_6;

/**

 * 发现,GenDemo05在使用Point类的时候,需要加入一个属性类型的声明,

 * 而且加入之后再取出属性的时候本身也变得非常容易,不用再使用向下转型了。

 * 而且,使用上面的操作有一点不方便之处,如果此时设置的内容不是整型,那么程序中将出现错误。

  */

publicclass GenDemo06 {

 

   

    publicstaticvoid main(String[] args) {

       Point<String>p=new Point<String>();

       p.setX("String");

       //p.setY(12); //错误

       //所以,加入泛型之后,可以对程序的操作起到更加安全的目的。

       String x=p.getX();

       String y=p.getY();

        System.out.println("X的坐标是:"+x);

        System.out.println("y的坐标是:"+y);

       }

    }

1.2 引用泛型

 1.2.1构造方法中引用泛型

1)实体类Point<T>

package fanXing7_8;

/**

 * 在构造方法上引用泛型

 *在一般开发中,经常使用构造方法设置属性的内容。

 *那么此时实际上构造方法依然可以使用泛型的类型。

 *

 */

publicclass Point<T> {

private Tx;//x的属性的类型由外部决定。

private Ty;//y属性的类型由外部决定

public Point(T x,T y){//构造方法

    this.setX(x);

    this.setY(y);

}

public T getX(){

    returnx;}

publicvoid setX(T x){

    this.x=x;

}

public T getY(){

    returny;

}

publicvoid setY(T y){

    this.y=y;

    }

}

 

2)测试类1- GenDemo07

package fanXing7_8;

 

publicclass GenDemo07 {

 

    publicstaticvoid main(String[] args) {

       Point<Integer> p=new Point<Integer>(10,20);

       Integer x=p.getX();

       Integer y=p.getY();

       System.out.println("x的坐标是:"+x);

       System.out.println("y的坐标是:"+y);

}

}

 

1.2.2 泛型的类型擦除

类型擦除:使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉,而这个过程就叫做,类型擦除。

 3)测试类2- GenDemo08

package fanXing7_8;

/**

 * 如果在使用的时候没有指定泛型的话,则表示擦除泛型。

 * 泛型一旦擦除之后,将按照Object进行接收,以保证程序不出现任何的错误。

 *

 */

publicclass GenDemo08 {

 

    publicstaticvoid main(String[] args) {

       //Point p=new Point(10,20);//有警告,

       Point<Object> p=new Point<Object>(10, 20);//去除警告信息,擦除泛型。

       //但是,以上的操作虽然去掉了警告信息,但是有多余了,而且有些搞笑。

       int x=(Integer)p.getX();

       int y=(Integer)p.getY();

       System.out.println("x的坐标是:"+x);

       System.out.println("y的坐标是:"+y);

}

}

1.3 通配符

1.3.1   ?通配符!

在使用泛型类的时候,既可以指定一个具体的类型,如List<String>就声明了具体的类型是String;也可以用通配符?来表示未知类型。

如:List<?>就声明了List中包含的元素类型是未知的。通配符所代表的其实是一组类型,但具体的类型是未知的。

注意:但是List<?>并不等同于List<Object>List<Object>实际上确定了List中包含的是Object及其子类,在使用的时候都可以通过Object来进行引用。而List<?>则其中所包含的元素类型是不确定。

1)实体类Point<T>

package tongPeiFu9_10;

/**

 * 在进行对象转型的时候可以使用自动的向转型,但是在使用泛型的时候却没有此操作。

 * */

publicclass Point<T> {//表示坐标

    private Tx;//x属性的类型由外部决定

    private Ty;//y属性的类型由外部决定

    public T getX(){

       returnx;

       }

    publicvoid setX(T x) {

       this.x = x;

    }

    public T getY(){

       returny;

       }

publicvoid setY(T y){

    this.y=y;

    }}

 

 

2)测试类1- GenDemo09

package tongPeiFu9_10;

 

publicclass GenDemo09 {

publicstaticvoid main(String[] args) {

       Point<Object> P1 =new Point<Object>();

       Point<Integer> p2 =new Point<Integer>();

       //p1=p2; //此时无法转换

      /**

       * 此时的程序发现,根本就无法进行转换的操作。

       * 此时的程序实际上已经完全不属于对象的转型操作了,属于一个大的类型和小类型的划分。

       * 例如:将 Point<Object>p1 =new Point<Object>();表示为整个商场的全部产品,而

       * Point<Integer> p2 =new Point<Integer>();表示每一个顾客购买的商品。如果现在执行p1=p2;

       * 那么就意味着,本顾客所购买的商品中的全部商品。这样肯定说不同,所以不能接收。

       *

       */

    }

}

3)测试类2- GenDemo10

package tongPeiFu9_10;

//程序中的?表示的是可以接收任意的泛型类型,但是只是接收输出,并不能修改。

publicclass GenDemo10 {

publicstaticvoid main(String[] args) {

       Point<Object> p1 =new Point<Object>();

       Point<Object> p2 =new Point<Object>();

       fun(p1);

       fun(p2);

       }

    //表示,此时可以接收任意的类型

    publicstaticvoid fun(Point<?> po){//?通配符!

       System.out.println(po.getX());

       System.out.println(po.getY());

       }}

 

1.3.2         泛型上限

(1)       实体类Point<T extends Number>

package FanXing_SX11_13;

/**

 * @author泛型上限

 * 上限就是指一个的操作泛型最大的操作父类,例如,现在最大的上限设置”Number“类型,那么此时,所能接收到的类型

 * 只能是Nnmber及其子类(Integer).

 * */

//泛型的上限通过以下的语法完成:? extends

 

publicclass Point<Textends Number> {

    private Tx;

    private Ty;

    public T getX(){

       returnx;

       }

    publicvoid setX(T x){

       this.x=x;

      

    }

    public T getY(){

       returny;

    }

    publicvoid setY(T y){

       this.y=y;

    }

    /*以上的泛型类型明确的指出,最大的父类是Nunber,能设置的内容只能是其子类IntegerFloat等等。

     *

     * */

}

package FanXing_SX11_13;

/**

 * @author泛型上限

 * 上限就是指一个的操作泛型最大的操作父类,例如,现在最大的上限设置”Number“类型,那么此时,所能接收到的类型

 * 只能是Nnmber及其子类(Integer).

 * */

//泛型的上限通过以下的语法完成:? extends

 

publicclass Point<Textends Number> {

    private Tx;

    private Ty;

    public T getX(){

       returnx;

       }

    publicvoid setX(T x){

       this.x=x;

      

    }

    public T getY(){

       returny;

    }

    publicvoid setY(T y){

       this.y=y;

    }

    /*以上的泛型类型明确的指出,最大的父类是Nunber,能设置的内容只能是其子类IntegerFloat等等。

     *

     * */

}

(2)       测试类1- GenDemoll

package FanXing_SX11_13;

publicclass GenDemoll {

    publicstaticvoid main(String[] args) {

       Point<Integer> p1 =new Point<Integer>();//设置的是Number的子类

       //由于已经定义了泛型,可接受的类型为Nnmber,此时设置的泛型类型是字符串的话,

       //则会出现错误.

       Point<Integer> p2=new Point<Integer>();

       fun(p2);

}

    //而且使用泛型的上限也可以在方法上使用,例如:就收参数。

    publicstaticvoid fun(Point<?extends Number> po){

       System.out.println(po.getX());

       System.out.println(po.getY());

       }

}

 

1.3.3         泛型下限

(1)       实体类Point<T>

package FanXing_XX14;

/* 指的是只能设置其具体的类或父类。

 * 设置方法如下:

 * ? super

 例:(String 类)<? super String>

 */

publicclass Point<T> {

privatex;

private Ty;

public T getX(){

    returnx;

}

publicvoid setX(T x){

    this.x=x;

}

public T getY(){

    returny;

}

publicvoid setY(T y){

    this.y=y;

}

}

2)测试类1- GenDemo14

package FanXing_XX14;

//在方法中设置下限,

publicclass GenDemo14 {

publicstaticvoid main(String[] args) {

       Point<String> p1 =new Point<String>();

       Point<Object> p2 =new Point<Object>();

       fun(p1);

        fun(p2);

       }

publicstaticvoid fun(Point<?super String>po){//表示,此时可以用String

    System.out.println(po.getX());

    System.out.println(po.getY());

    }

}

1.4 泛型接口

1)泛型接口类Demo<T>

  package fanXing_JieKou15_16;

/**

 * @author泛型接口

 * 泛型不光可以在类上使用,还可以在接口中定义。

 * 创建格式:

 *         interface 接口名称<泛型类型,泛型类型,¡¤¡¤¡¤>{}

 *

 * @param<T>

 */

publicinterface Demo<T> {//定义泛型接口

publicvoid print(T param);//此抽象方法中使用了泛型类型

}

2)实现泛型接口类 1- DemoImpl1<T>

package fanXing_JieKou15_16;

/*泛型接口定义完成之后,下面就需要定义子类实现此接口,实现的方法有

 *

 */

//一种实现手段

publicclass DemoImpl1<T>implements Demo<T>{

 

   

    publicvoid print(T param) {

       System.out.println("param="+param);

       }

}

3)实现泛型接口类 2- DemoImpl2

package fanXing_JieKou15_16;

/**

 *

 *在实现接口的时候还有第二种做法

 *

 */

publicclass DemoImpl2implements Demo<DemoImpl2>{

     //此时print()方法中,只能接受DemoImpl2对象的实例;

    //这是因为实现接口的时候,所使用的接口类型,已经定义为Demo<DemoImpl2>

    //所以,只能在实现DemoImpl2类的对象,所传的参数才可以使用

    publicvoid print(DemoImpl2 param) {

    System.out.println("param="+param);

       }}

4)测试类 1- GenDem015

package fanXing_JieKou15_16;

publicclass GenDem015 {

    publicstaticvoid main(String[] args) {

       //实例化一个Demo接口类型的demo对象,通过实现了Demo接口的DemoImpl1<String>类来来实现!

       Demo<String>demo=new DemoImpl1<String>();

demo.print("hello");

    }

}

5)测试类 2- GenDemo16

package fanXing_JieKou15_16;

/**

 * 使用DemoImpl2接口的方法,

 * 此时由于接口已经定义了类型,所以,必须使用接口所定义的类型参数

*/

publicclass GenDemo16 {

    publicstaticvoid main(String[] args) {

    Demo<DemoImpl2>demo=new DemoImpl2();

    demo.print(new DemoImpl2());

}

}

1.5 泛型方法

1)实体类Demo

package fanXing_FangFa17_18;

/**

 * 泛型除了在类中定义外,还可以在方法上定义,而且在方法上使用泛型,

 * 此方法所在的类不一定是泛型的操作类。

 */

publicclassDemo {

 

    public <T> T print(T param){

       return param;

    }}

(2)       测试类 1- GenDemo17

package fanXing_FangFa17_18;

//Demo类中的Print()方法里面接收泛型的类型,而且此方法的返回值也是指定的泛型类型。

//下面使用以上的类进行操作。

publicclassGenDemo17 {

 

    publicstaticvoid main(String[] args) {

    Demo d=new Demo();

    System.out.println(d.print(1));//如果输入1表示类型是Integer

 

    }

 

}

(3)       测试类 2- GenDemo18(接收数组)

package fanXing_FangFa17_18;

/**

 * 也可以将方法的返回值定义成一个泛型的数组。

 */

publicclassGenDemo18 {

    publicstaticvoid main(String[] args) {

       Integer i[]=fun(1,2,3,4,5,6,7,8,9);

        for(int x:i){

        System.out.println(x);

        }}

     publicstatic <T> T[] fun(T... param){

       return param;//返回数组

     }

 

}

1.6 泛型的嵌套设置

 1)实体类 1- Info<T>

package genericscdemo09;

/**

 *

 * @author张占忠

 * @version泛型的嵌套的设置!

 *

 *现在只是

 * @param<T>

 */

publicclassInfo<T> {

    private Tparam;

    public T getParam(){

       returnparam;

    }

    publicvoid setParam(T param){

       this.param=param;

    }

    }

(2) 实体类 2- Person<T>

package genericscdemo09;

//之后定义Person类型。

publicclass Person<T> {

private Tinfo;

public T getInfo(){

    returninfo;

}

publicvoid setInfo(T info){

    this.info=info;

}

 

}

3)测试类Test

package genericscdemo09;

//此时如果要将Info的类型设置到Person之中,那么同时既要指定Person的泛型类型,

//又要指定Info中的泛型类型。

publicclassTest {

 

    publicstaticvoid main(String[] args) {

       Person<Info<String>>per=new Person<Info<String>>();

       per.setInfo(new Info<String>());

       per.getInfo().setParam("mldnjava");

       System.out.println(per.getInfo().getParam());

       System.out.println();

       //以上操作,在后面将会有所应用。

}

}

 

 

三、泛型-操作范例

  1)接口类

package genericscdemo10;

/*此时最好的设计是需要定义一个表示信息的操作标准。但是此时这个标准肯定使用接口实现,但是现在

 * 在接口中并不编写任何的操作。

 *

 * 此时定义的接口没有任何的操作代码,此时的接口在设计上称为标示接口,表示一种能力。

 */

publicinterface Info {}

 

2)实体类 1- Person<Textends Info>

package genericscdemo10;

//定义实体PersonPerson类中的信息只能由Info的子类决定,所以此时定义了上限。

publicclass Person<Textends Info> {

private Tinfo;

publicT getInfo(){

    returninfo;

    }

publicvoid setInfo(T info){

    this.info=info;

}}

 

3)实体类 2- Basic

package genericscdemo10;

 

publicclass Basicimplements Info{

    private Stringname;

    privateintage;

    public Basic(){

       super();

    }

    public Basic(String name,int age){

       super();

       this.name=name;

       this.age=age;

       }

    public String getName(){

       returnname;

    }

    publicvoid setName(String name){

       this.name=name;

    }

    publicint getAge() {

       returnage;

       }

    publicvoid SetAge(int age){

       this.age=age;

       }

    public String toString(){

       return"人的信息"+"\n"+"\t|-姓名:"+this.getName()+"\n"+"\t|-年龄:"+this.getAge();

    }

 

}

4)实体类 3- Contact:

package genericscdemo10;

//联系方式子类

publicclass Contactimplements Info{

    private Stringaddress;

    private Stringzipcode;

    private Stringziocode;

    public Contact(){

       super();

    }

    public Contact(String address,String zipcode){

       super();

       this.address=address;

       this.zipcode=zipcode;

    }

    public String getAddress(){

       returnaddress;

    }

    publicvoid setAddress(String address){

       this.address=address;

    }

    public String getZipcode(){

       returnziocode;

    }

    publicvoid setZipcode(String zipcode){

       this.zipcode=zipcode;

    }

public String toString(){

    return"地址信息:"+"\n"+"\t-地址:"+this.getAddress()+"\n"+"\t|-邮编:"+this.getZipcode();

}

}

(5) 测试类 - TestPerson1

package genericscdemo10;

 

publicclass TestPerson1 {

 

    //以上的Person中的信息属性,只能是Info的子类,从而保障了操作的正确性

    publicstaticvoid main(String[] args) {

       Person<Basic> per=new Person<Basic>();

       per.setInfo(new Basic("张三",30));

       System.out.println(per.getInfo());

       Person<Contact> per2= new Person<Contact>();

       per2.setInfo(new Contact("北京市","100080"));

       System.out.println(per2.getInfo());

}

}

四、泛型-总结:

 1、泛型如果没有设置的类型的话,则会进行擦除,擦除之后按照Object进行接收

 2、泛型-通配符可以通过 ”?””? exrebds”? super指定泛型的操作界限

 3、泛型可以在接口上设置,指定泛型接口的子类需要明确的给出操作的类型

 4、泛型还可以在方法中,直接定义并实现!

 5、泛型可通过,两个泛型类相互嵌套,进行参数类型的界限!

 

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

原创粉丝点击