博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA泛型笔记
阅读量:7030 次
发布时间:2019-06-28

本文共 4168 字,大约阅读时间需要 13 分钟。

泛型是JDK 1.5的一项新特性,它的本质是参数化类型(Parameterized Type),即所操作的数据类型在定义时被指定为一个参数。当我们使用的时候给这个参数指定不同的对象类型,就可以处理不同的对象。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。

一、泛型实现方式

泛型声明方式:<占位符>

占位符有两大类:

  1. 普通占位符,E, T, K, V一般是单字母大写,表示接收特定的类型。
  2. 通用占位符,也叫通配符,占位符中包含“?”问号,表示接任意数据类型或者指定范围数据类型。

泛型类

泛型类和普通类的区别就是类定义时,在类名后加上泛型声明。泛型类的内部成员、方法就可以使用声明的参数类型。泛型类最常见的用途就是作为容纳不同数据类型的容器类,比如Java集合容器类。

class GenericClass
{ private T value; public T getValue() { return value; } public void setValue(T value) { this.value = value; }}

泛型接口

和泛型类一样,泛型接口在接口名后添加泛型声明,接口方法就可以直接使用声明的参数类型。

实现类在实现泛型接口时需要指明具体的参数类型,不然默认类型是 Object,这就失去了泛型接口的意义。

interface genericInterface
{ K getKey(); V getValue();}

未指明类型的实现类,默认是 Object 类型:

class GenericClass implements genericInterface{    @Override    public Object getKey() {        return null;    }    @Override    public Object getValue() {        return null;    }}

指明了类型的实现:

class GenericClass implements genericInterface
{ @Override public String getKey() { return null; } @Override public Object getValue() { return null; }}

泛型方法

泛型方法指的是使用泛型的方法。如果这个方法所在的类是个泛型类,直接使用类声明的参数类型。

如果这个方法所在的类不是泛型类或者他想要处理不同于泛型类所声明的参数类型,这时候我们就需要使用泛型方法。即在方法前加入泛型声明,方法就可以直接使用声明的参数类型。

class GenericClass {    private Object value;    public 
T getValue(){ return (T)value; } public void setValue(Object value){ this.value = value; }}

方法getValue()就是泛型方法,调用代码如下:

GenericClass genericClass = new GenericClass();genericClass.setValue(123);Integer value = genericClass.getValue();

二、泛型的优点

数据类型安全

泛型的主要目的通过参数类型检查,提高JAVA程序数据类型的安全,提早发现错误,避免ClassCastException 异常发生。

List list = new ArrayList();list.add("test generic");list.add(123);// 注:123会转换成Integer对象list.add(null);

当不实用泛型的时候,上面代码的使用是被允许的,我们可以放入任何对象,当我们按照某种对象类型去取数据就会出现ClassCastException 异常。

//List
list = new ArrayList
();List
list = new ArrayList();list.add("test generic");//list.add(123);list.add(null);

List是泛型接口,当我们这样使用的时候,“123”这个元素是不被允许使用的。

消除类型转换

当我们不使用泛型时,每次取出集合中的元素都需要我们强制转换成我们需要的元素。(Object->Class Type)。

List list = new ArrayList();list.add("test generic");String s = (String) list.get(0);

“test generic”存入list是一个Object的对象,取出来是我们需要转换成我们要的字符串String类型。

List
list = new ArrayList();list.add("test generic");String s = list.get(0);

使用泛型后list.get(0)中取出来的数据类型,就是我们存入时的String类型。

简码,提高效率

通过泛型的应用,做到了简码,而且JVM中类文件也相应的减少。JVM几乎没有做任何的更改,所有的类型校验,类型转换都是在编译器阶段完成。

三、通配符

无限制通配符<?>

定义时不关心或者不确定实际要操作的数据是什么类型,可以使用无限制通配符(尖括号里一个问号,即 <?> ),表示可以持有任何类型。

class GenericClass
{ private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return "GenericClass{" + "data=" + data + '}'; }}

泛型类定义

public static void print(GenericClass
context){ System.out.println(context);}

通配符定义的方法参数类型

GenericClass
integerGenericClass = new GenericClass<>();integerGenericClass.setData(123);GenericClass
stringGenericClass = new GenericClass<>();stringGenericClass.setData("123");print(integerGenericClass);print(stringGenericClass);

使用时?是一个万能的类型,T只能是具体的类型

上界通配符 <? extends E>

在类型参数中使用extends表示这个泛型中的参数必须是 E 或者 E 的子类,这样有两个好处:

  1. 如果传入的类型不是E或者E的子类,编辑不成功
  2. 泛型中可以使用E的方法,要不然还得强转成E才能使用
List
list = new ArrayList
(){
{add(new Integer(456));add(new Long(456L)); }};list.add(null);//list.add(new Integer(123));//list.add(new Long(123L));System.out.println(list.size());Number number = list.get(0);

当使用上边界通配符时,是不允许往里存数据的,不确定具体元素类型。

下界通配符 < ? super E>

在类型参数中使用super表示这个泛型中的参数必须是E或者E的父类。

用于灵活写入或比较,使得对象可以写入父类型的容器,使得父类型的比较方法可以应用于子类对象。

List
list = new ArrayList(){
{add(new B()); add(new C());}};list.add(null);list.add(new C());list.add(new B());//list.add(new A());Object object = list.get(0);

C是B的子类,B是A的子类。当使用下界通配符时,是允许存放E和E的子对象数据的,因为子类对象的引用可以赋值给父类对象的引用(顶级父类是Object),所以取出来的数据类型是Object.

四、总结

  • 在实例化的时候,就必须声明泛型具体是一个什么类型。
  • 使用泛型、通配符提高了代码的复用性。
  • 把一个对象分为声明、使用两部分的话。泛型侧重于类型的声明上代码复用,通配符则侧重于使用上的代码复用。泛型用于定义内部数据类型的不确定性,通配符则用于定义使用的对象类型不确定性。
  • 如果类型参数在方法声明中只出现一次,可以用通配符代替它。
  • 不能同时声明泛型通配符上界和下界。

转载地址:http://kigxl.baihongyu.com/

你可能感兴趣的文章
Java 接口
查看>>
Android 微信第三方登录
查看>>
硬盘的读写原理
查看>>
实例 centos自动挂载、备份windows共享文件夹,并删除第7日前当天的备份
查看>>
LNMP下动静分离部署phpmyadmin软件包
查看>>
如何写更好的自动化测试用例
查看>>
60再谈指针
查看>>
repost
查看>>
android异步加载AsyncTask
查看>>
GCC Stack-Smashing Protector
查看>>
虚拟机Visualbox安装Ubuntu Server
查看>>
用带余除法可以解决一切部分分式的题目
查看>>
vs 生成事件
查看>>
jmeter 实战项目总结2——微信端
查看>>
php.ini 中文版
查看>>
即时通信客户端流程,
查看>>
布隆过滤器redis缓存
查看>>
01-数据仓库之数据建模
查看>>
Nginx 安装
查看>>
hidesBottomBarWhenPushed 设置为NO的问题
查看>>