JAVA 泛型理解

作者: Mr_step | 来源:发表于2017-02-20 16:39 被阅读790次

一直对java泛型一知半解,决定好好理解一下泛型.


泛型的基本使用:

我们最常用到泛型的地方可能是arraylist中,如:ArrayList<Integer> intList = new ArrayList<Integer>();它可以构造各种类型的变量来组装成不同的list而不必对每一个类型都创建一个Arraylist的类,

  • 定义及使用:
//定义
class Person<T>{// 此处可以随便写标识符号   
    private T x ;        
    private T y ;        
    public void setAge(T x){//作为参数  
        this.x = x ;  
    }  
    public void setName(T y){  
        this.y = y ;  
    }  
    public T getAge(){//作为返回值  
        return this.x ;  
    }  
    public T getName(){  
        return this.y ;  
    }  
};

因为T表示派生自Object类的任何类,所以尖括号T中必须是继承自Object,如:String,Interger,不能使用原始的类型,如int,double.

//使用
//设置年龄 
Person<Integer> p = new Person<Integer>() ;   
p.setAge(new Integer(100)) ;   
System.out.println(p.getAge());   
//设置名字  
Person<String> p = new Person<String>() ;   
p.setName(new String("name")) ;   
System.out.println(p.getName()); 

使用的Class<T> object来传递类的class对象

我们在解析Json的时候:

public static List<SuccessModel> parseSuccessArray(String response){  
    List<SuccessModel> modelList = JSON.parseArray(response, SuccessModel.class);  
    return modelList;  
}  

这样做比较的死板,我们可以吧successmodel抽取出来,当做一个变量,这样就可以使用到泛型了,如下:

public static <T> List<T> parseArray(String response,Class<T> object){  
    List<T> modelList = JSON.parseArray(response, object);  
    return modelList;  
}  

注意到,我们用的Class<T> object来传递类的class对象,即我们上面提到的SuccessModel.class,这样就可以传递任意的class来解析不同的数据.

//待续。。。。

进阶

类型绑定:

有时候定义泛型的时候可能希望泛型类型只能是一部分类型,就是给泛型指定一个界限,
定义形式为:

<T extends BoundingType>  

T和BoundingType可以是类,也可以是接口。另外注意的是,此处的”extends“表示的子类型,不等同于继承。在这里extends后的BoundingType可以是类,也可以是接口.

通配符:

通配符用?表示无边界通配符,通配符的意义就是他是一个未知的符号,可以表示任意的类,如:

Point<?> point;  
point = new Point<Integer>(3,3);  
point = new Point<Float>(4.3f,4.3f);  
point = new Point<Double>(4.3d,4.90d);  
point = new Point<Long>(12l,23l); 
  • 通配符?和T的区别:
    泛型变量T不能在代码用于创建变量,只能在类,接口,函数中声明以后,才能使用。
    而无边界通配符?则只能用于填充泛型变量T,表示通配任何类型
    如:
Box<?> box;  
box = new Box<String>(); 

?只能出现在Box<?> box;中,其它位置都是不对的

  • 通配符?的extends绑定:
    通配符可以和泛型一样加以限定。如:
Point<? extends Number> point;

注意:利用<? extends Number>定义的变量,只可取其中的值,不可修改
如:

Point<? extends Number> point = new Point<Integer>(3);

point的类型是由Point<? extends Number>决定的,并不会因为point = new Point<Integer>(3);而改变类型。如果会改变类型那么<? extends Number>就失去了作用。但取值时,正由于泛型变量T被填充为<? extends Number>,所以编译器能确定的是T肯定是Number的子类,编译器就会用Number来填充T。

通配符?的super绑定:

如果说 <? extends XXX>指填充为派生于XXX的任意子类的话,那么<? super XXX>则表示填充为任意XXX的父类.
如:

class CEO extends Manager {  
}  
  
class Manager extends Employee {  
}  
  
class Employee {  
}  

List<? super Manager> list;  
list = new ArrayList<Employee >();
list = new ArrayList<Manager >();
list = new ArrayList<CEO >();//编译会报错

因为CEO类已经不再是Manager的父类了。所以会报编译错误。
注意:super通配符表示的实例内容:能存不能取
先看存的部分:

List<? super Manager> list;  
list = new ArrayList<Employee>();  
//存  
list.add(new Employee()); //编译错误  
list.add(new Manager());  
list.add(new CEO()); 

为什么会报编译错误呢?因为
编译器无法确定<? super Manager>的具体类型,但唯一可以确定的是Manager()、CEO()肯定是<? super Manager>的子类,所以肯定是可以add进去的。但Employee不一定是<? super Manager>的子类,所以不能确定,不能确定的,肯定是不允许的,所以会报编译错误。
super和extends相反,使用super关键字时,往里存的只要是Employee的子类,就会强制转换为Employee存储,但是取出来时应该都为父类Employee所以没有意义,所以我们认为super通配符:能存不能取;

总结

extends 和 the ? super 通配符的特征,我们可以得出以下结论:
◆ 如果你想从一个数据类型里获取数据,使用 ? extends 通配符(能取不能存)
◆ 如果你想把对象写入一个数据结构里,使用 ? super 通配符(能存不能取)
◆ 如果你既想存,又想取,那就别用通配符。

参考链接:
夯实JAVA基本之一 —— 泛型详解(1):基本使用
夯实JAVA基本之一——泛型详解(2):高级进阶

相关文章

  • 泛型琐碎之泛型上下限

    泛型的命名规范 为了更好地去理解泛型,我们也需要去理解java泛型的命名规范。 为了与java关键字区别开来,ja...

  • java泛型理解及应用

    内容: java泛型理解及应用

  • Java 泛型

    java 泛型 很多朋友对java的泛型不是很理解,很多文章写的已不是很清楚,这篇博客对java泛型进行 一个总结...

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 反射获取泛型类型

    参考:步步理解 JAVA 泛型编程(一)

  • 泛型

    java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一Java泛型深入理解加泛型面试数组的协变性与范型的不可变性

  • Java 泛型擦除原理

    问:请比较深入的谈谈你对 Java 泛型擦除的理解和带来的问题认识? 答:Java 的泛型是伪泛型,因为在编译期间...

  • java 泛型

    很多朋友对Java的泛型不是很理解,很多文章写的已不是很清楚,这篇博客对java泛型进行 一个总结。 泛型的转换:...

  • JDK1.5后增加了泛型,那么为什么要有泛型呢?我们该如何自定义

    本篇主要讲解java泛型的理解、集合中简单使用泛型、自定义泛型结构(包括类、接口、方法)。 一、什么是泛型? 通俗...

  • [Java菜鸟系列] 「林彪」教你"通配符泛型

    J007- [Java菜鸟系列] 「林彪」教你"通配符泛型" 菜鸟:Java方法参数中的泛型通配符要怎么理解?老湿...

网友评论

    本文标题:JAVA 泛型理解

    本文链接:https://www.haomeiwen.com/subject/zpzxmttx.html