Java详细分析讲解泛型

 更新时间:2022年05月07日 10:10:50   作者:星鸦wyk  
在正式进入内容之前说明一下:泛型的内容太多,也太复杂。这里因为Java中写数据结构的时候会使用到,所以加上。关于泛型我找了挺多文章,再结合自己的理解,尽可能将其讲清楚。不求会使用泛型,只要求后面数据结构出现泛型的时候能够知道是在干什么即可

1.泛型概念

泛型就是将类型参数化

所谓类型参数化就是将类型定义成参数的形式,然后在使用此类型的时候的时候再传入具体的类型

到这我们可以看出来:泛型在定义的时候是不知道具体类型的,需要在使用的时候传入具体的类型,泛型可以用在类、接口和方法中,这样做的好处是一个泛型可以适用多种情况

2.泛型的使用

2.1泛型类语法

public class 类名<T> {......}

<T>表示这是一个泛型类,T是type的首字母大写,除此之外的名称还有:

E:element

K:key

V:vlaue

N:number

<>中可以有多个类型参数,中间使用逗号隔开

2.2泛型方法语法

public<泛型类型> 返回值 方法名(泛型类型 参数) {......}

2.3泛型接口语法

public interface 接口名<泛型类型> {......}

2.4泛型在main方法中的使用

下面写一个泛型类来引出后面的内容

class Fc<T>{
    private T a;
    public T get (T data) {
        this.a=data;
        return a;
    }
}

前面说过泛型是在使用的时候再传入具体的类型,所以在实例化上面泛型类的时候要指定类型。具体方式如下

类名<具体类型>变量名=new 类名<具体类型>();

注意:

  • 等号右边<>中可以不写具体类型,编译器可以根据上下文推导出此处的类型
  • <>中只能写入类,所以如果是基本数据类型,就需要写入其对应的包装类,包装类除int是Integer,char包装类是Character外,其余均是首字母大写
  • Java中不能创建泛型数组,至于原因要从Java中泛型的机制说起

3.擦除机制

Java实现泛型是依靠这个擦除机制的,这个机制目前来讲过于复杂,只说结果

Java编译器在编译的时候会去掉类型参数,而对于泛型类型来说,如果指定上界会用上界类型进行替换,没有指定上界则会以Object来进行替换

所以在编译的时候泛型类型都被替换成了Object,编译后的class文件是不包含任何泛型信息的,即泛型信息不会进入到运行时阶段

但Java的数组需要进行运行期类型检查,而由于类型擦除,造成数组运行期类型检查不能正常进行,破坏了Java数组运行期类型检查的机制

4.泛型的上界

所谓泛型的上界就是对传入的类型变量进行约束,指定哪些类型可以传入,哪些不行,语法如下:

class 类名<类型参数extends类型边界> {......}

还是以上面的泛型类为例,现在改成如下情况:

class Fc<E extends Number >{
    private E a;
    public E get (E data) {
        this.a=data;
        return a;
    }
}

那么此时Fc就只能传入Number或者其子类

5.通配符

通配符就是“?”在泛型中使用,它是用来解决泛型无法协变的问题,那什么是协变?

假设有两个类A和B,A继承B,那么泛型Fc<A>应该也是Fc<B>的子类,但泛型不支持这样的父子关系

基于上面的情况,所以需要使用通配符

直接写两个类,A继承B

class B {
}
class A extends B {
}

现在把<B>改成<?>

5.1通配符的上界

通配符也可以指定界限,语法和泛型的上界类似

<? extends 类型边界>

假设<? extends Number>,那么可以传入的是Number及其子类

但需要注意的是:通配符的上界只能用来读取数据,不能用来写入数据

因为我们只知道里面可以传入什么类型的数据,但具体是什么类型我们不知道,所以也就无法对数据进行修改,但是读取则可以直接用父类对象来进行接收读取出来的数据

5.2通配符的下界

下界使用的是super

<? super 类型边界>

<? super Integer>表示可以传入Integer或者其父类

通配符下界可以进行写入数据,但不能用来读取数据

原因也很简单,里面可以传的类都是Integer或者它的父类,写进去的数据可以进行转化,但读取数据用哪一个父类对象接收则不好确定了

6.包装类

由于Java中基本数据类型不是继承Object类,所以为了泛型能够支持基本数据类型,每一个基本数据类型都有各自的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

6.1装箱和拆箱

装箱就是把基本数据类型改为对应的包装类类型,拆箱就是和装箱相反的操作

Java中提供了自动装箱和拆箱机制,但还是先来看下手动装箱和拆箱的操作

//手动装箱
int i=10;
Integer j=Integer.valueOf(i);  //第一种操作
Integer j=new Integer(i);      //第二种操作
//手动拆箱
int a=j.intValue();

自动装箱和拆箱的话代码就要少的多

int i=10;
Integer j=i;  //自动装箱
int a=j;      //自动拆箱

关于int的包装类有一个比较有趣的地方,装箱使用了valueOf方法,其源码如下:

可以看到传给方法的参数首先是和IntegerCache进行比较,如果参数的值是在某个范围中,那么返回的是数组里面的元素,否则返回新的对象

那我们来看看这个IntegerCache

也就是说-128<=i<=127的时候返回的是类中的数组的元素,那么就会有一个情况如下:

原因和上面所讲一样

泛型结束,后面数据结构的时间复杂度和空间复杂度这两个概念就不写了,下一篇直接到顺序表

到此这篇关于Java详细分析讲解泛型的文章就介绍到这了,更多相关Java泛型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring 异常处理的各种姿势总结

    Spring 异常处理的各种姿势总结

    这篇文章主要介绍了Spring 异常处理,总结分析了Spring 异常处理的各种常见操作技巧与相关使用注意事项,需要的朋友可以参考下
    2020-05-05
  • springboot整合mybatis将sql打印到日志的实例详解

    springboot整合mybatis将sql打印到日志的实例详解

    这篇文章主要介绍了springboot整合mybatis将sql打印到日志的实例详解,需要的朋友可以参考下
    2017-12-12
  • RabbitMQ消息拒绝如何解决

    RabbitMQ消息拒绝如何解决

    这篇文章主要介绍了RabbitMQ消息拒绝如何解决问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java多线程之volatile关键字及内存屏障实例解析

    Java多线程之volatile关键字及内存屏障实例解析

    volatile是JVM提供的一种最轻量级的同步机制,因为Java内存模型为volatile定义特殊的访问规则,使其可以实现Java内存模型中的两大特性:可见性和有序性。这篇文章主要介绍了Java多线程之volatile关键字及内存屏障,需要的朋友可以参考下
    2019-05-05
  • 讲解ssm框架整合(最通俗易懂)

    讲解ssm框架整合(最通俗易懂)

    这篇文章主要介绍了讲解ssm框架整合(最通俗易懂),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • java中字符进行全角半角转换示例代码

    java中字符进行全角半角转换示例代码

    全角:指一个字符占用两个标准字符位置,而半角:指一字符占用一个标准的字符位置,在日常开发中经常会遇到全角半角转换的要求,下面这篇文章主要给大家介绍了关于java中字符进行全角半角转换的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-08-08
  • feign调用第三方接口,编码定义GBK,响应中文乱码处理方式

    feign调用第三方接口,编码定义GBK,响应中文乱码处理方式

    这篇文章主要介绍了feign调用第三方接口,编码定义GBK,响应中文乱码处理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java ScheduledExecutorService的具体使用

    Java ScheduledExecutorService的具体使用

    ScheduledExecutorService有线程池的特性,也可以实现任务循环执行,本文主要介绍了Java ScheduledExecutorService的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-05-05
  • Mybatis-Plus中IdType.AUTO局部配置不生效的问题解决

    Mybatis-Plus中IdType.AUTO局部配置不生效的问题解决

    本文主要介绍了Mybatis-Plus中IdType.AUTO局部配置不生效的问题解决,数据库插入数据时,id的默认生成方式还是雪花算法,局部配置没有生效,下面就来解决一下,感兴趣的可以了解一下
    2023-09-09
  • 浅析Java中的GC垃圾回收器的意义及与GC的交互

    浅析Java中的GC垃圾回收器的意义及与GC的交互

    这篇文章主要介绍了Java中的GC垃圾回收器的意义及与其的交互,GC是Java虚拟机JVM的一项重要特性,需要的朋友可以参考下
    2015-12-12

最新评论