泛型泛型擦除【java基础—-泛型】

大家好,又见面了,我是你们的朋友全栈君。

目录 1.什么是泛型 1.1泛型概念: 1.2本质:参数化类型 1.3语法:, T 称为类型占位符,表示一种引用类型。 1.3 泛型定义(泛型类、泛型方法(泛型方法返回值是泛型的,泛型方法在普通类和泛型类里)): 1.4特点: 对于泛型特点(1)举个例子 : 没有使用泛型时的异常抛出 对于泛型特点(2)访问时不需要类型转换(拆箱),举例子List list = new ArrayList(); 对于泛型特点(3)不同泛型之间不能相互赋值,举例 对于泛型特点(3)泛型不存在多态,举例 2.泛型类、泛型接口、泛型方法 2.1泛型类 2.2泛型接口与泛型类相似,不举例子了 2.3泛型方法 2.4.疑惑,为什么有泛型类了,还要有泛型方法,泛型类与泛型方法有什么区别,泛型方法有什么好处? 3.为什么要使用泛型,泛型的好处: 3.1泛型的好处 3.2泛型类的好处 4.使用泛型注意点: 4.1不同泛型之间不能相互赋值,泛型不存在多态((检查机制)泛型特点(3)) 4.2要注意泛型擦除 4.3不能实例化泛型,例如 T t = new T(); 理由:泛型擦除T都没了 4.4泛型不能是基本类型(泛型本质是一种引用类型),还有考虑到泛型擦除后的类型,例如为Object类型时,Object不能存储基本类型int,double… 5.泛型擦除 5.1 泛型擦除概念: 5.2 由于泛型擦除出现的错误举例:



1.什么是泛型

1.1泛型概念:

Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter),这种参数类型可以用在接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

1.2本质:参数化类型

1.3语法:<T>, T 称为类型占位符,表示一种引用类型。

1.3 泛型定义(泛型类、泛型方法(泛型方法返回值是泛型的,泛型方法在普通类和泛型类里)):

10、泛型的定义是<T>(带尖角号的T),
例如定义一个泛型类:public class Stu<T>{ }
定义一个泛型方法(不在泛型类里):publilc <T> void testMethod() { }
或定义一个返回值类型是泛型的方法(不在泛型类里): public <T> T testMethod2(){return null}
注意,(在泛型类里 的返回值是泛型的方法)在定义了泛型类之后,在该类里想要返回值类型是一个泛型的方法(),
不用再<T>定义该方法是泛型啦,直接可以使用泛型的T: public T testMethod3(){return null}

1.4特点:

(1)编译时即可检查,非运行时抛出异常;

     (2)访问时不需要类型转换(拆箱);

     (3)不同泛型之间不能相互赋值,泛型不存在多态。

对于泛型特点(1)举个例子 : 没有使用泛型时的异常抛出

public class MyGenericTest {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(123);       //添加Integer对象
        list.add("zifu");    //添加String对象
        list.add(1.22);      //添加Double对象
        
        for(Object object: list) {
            //!!!使用,例如要进行运算使用
            Double num = (Double)object;
            System.out.println(num);
        }
    }
}

结果:Exception in thread “main” java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double at MyGenerics.MyGenericTest.main(MyGenericTest.java:28)

分析一下:编译通过,但是运行提示异常,类型转换异常,就是String类型不能转换为Double类型。我们在使用 list.add() 方法时,根据提示知道凡是Object对象都可以添加进去,但是要使用的时候忘了添加过什么类型的对象进去,根据提示强转过,但是由于添加进去一些类型不同的,强转可以在编译时通过,运行时异常抛出了。

这里就可以体现泛型的好处之一了:防止类型转换异常,提高代码的安全性。

对于泛型特点(2)访问时不需要类型转换(拆箱),举例子List<String> list = new ArrayList<String>();

查看ArrayList的访问4方法get()源码,看到返回值类型是泛型E,所以我们获取时就不用强转了。

//访问时不需要类型转换

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

package MyGenerics; import java.util.ArrayList; import java.util.List; public class MyGenericTest { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("dingdong"); list.add("zifu"); list.add("meimei"); for(int i = 0; i < list.size(); i++) { //!!!使用 String str = list.get(i);  //访问时不需要类型转换 System.out.println(str); } } }

对于泛型特点(3)不同泛型之间不能相互赋值,举例

对于泛型特点(3)泛型不存在多态,举例

另外这里报错原因是:Type mismatch: cannot convert from ArrayList<Integer> to ArrayList<Number>,类型不匹配的愿意

ps:泛型没有多态:是因为人家设计出来的初心就是为了提高代码重用,类型的转换都是自动和隐式的。(所以人家的真心不允许被辜负,就没多态了)

2.泛型类、泛型接口、泛型方法

2.1泛型类

语法:类名<T,……..>

举例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

package MyGenerics; import java.util.List; //Generic类,泛型类 //语法:类名<T> public class MyGeneric <T>{ //添加属性(泛型属性变量) T t; //添加方法(泛型参数) public void show(T t) { System.out.println(t); } //添加方法(泛型做为返回值) public T getT() { return t; } }

2.2泛型接口与泛型类相似,不举例子了

语法:接口名<T, …….>

2.3泛型方法

语法:[ 修饰符] <T> 返回值类型 方法名([参数列表])

2.4.疑惑,为什么有泛型类了,还要有泛型方法,泛型类与泛型方法有什么区别,泛型方法有什么好处?

为什么要使用泛型方法呢?(想换类型时,考虑方法的调用方便的好处,而类需要实例化)

因为泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候指明类型,更加灵活。

3.为什么要使用泛型,泛型的好处:

3.1泛型的好处

答:提高代码重用性,防止类型转换异常,提高代码的安全性。(也可以加上泛型特点(1)(2))

3.2泛型类的好处

答:使用泛型类可以解决重复业务的代码的复用问题,也就是业务颗粒的复用,同时使用泛型类型在编译阶段就可以确定,并发现错误,类型的转换都是自动和隐式的,提高了代码的准确率和复用率。

4.使用泛型注意点:

4.1不同泛型之间不能相互赋值,泛型不存在多态((检查机制)泛型特点(3))

4.2要注意泛型擦除

4.3不能实例化泛型,例如 T t = new T(); 理由:泛型擦除T都没了

4.4泛型不能是基本类型(泛型本质是一种引用类型),还有考虑到泛型擦除后的类型,例如为Object类型时,Object不能存储基本类型int,double…

5.泛型擦除

5.1 泛型擦除概念:

类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。

简单理解:在编译期间,所有的泛型信息都会被擦除掉。例如代码中定义的List<Object>和List<String>等类型,在编译后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。

5.2 由于泛型擦除出现的错误举例:

报错原因:Erasure of method MyGeneric(ArrayList<String>) is the same as another method in type MyGeneric<T>,

Erasure of method MyGeneric(ArrayList<Integer>) is the same as another method in type MyGeneric<T>

类型擦除的原因,擦除后 //方法重载,都变成了

public MyGeneric(ArrayList arrayList) { }

完美解释此处问题,但是却勾起小伙伴的另外一个问题,类型擦除了,为什么不同泛型之间不能相互赋值!!

因为检查机制的存在,编译器的工作是这样子滴:首先进行类型检查,检查类型不同,报错!如果类型相同,再进行类型擦除啦!!!(即进入擦除阶段,需要通过检查那一关)

举个例子,购买的衣服,需要相关人员先进行质量合格等方面的检查,检查通过,进入商城,消费者购买完撕掉了吊牌。。。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180164.html原文链接:https://javaforall.cn

原文地址:https://cloud.tencent.com/developer/article/2149758

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 连接 连接池产生原因 连接池实现原理 小结 TEMPERANCE:Eat not to dullness;drink not to elevation.节制
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。-- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelC
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。一、接口和抽象类类,即一个对象。先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类)。官方定义让人费解,但是记忆方法是也不错的 —包含抽象方法的类叫做抽象类。接口
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket一、引子文件,作为常见的数据源。关于操作文件的字节流就是 —FileInputStream&amp;FileOutputStream。
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_Aonqz
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程与多线程 线程是什么? 线程(Thread)是一个对象(Object)。用来干什么?Java 线程(也称 JVM 线程)是 Java 进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。 Ja
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket在面向对象编程中,编程人员应该在意“资源”。比如?1String hello = &quot;hello&quot;; 在代码中,我们
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 《程序兵法:Java String 源码的排序算法(一)》 文章工程:* JDK 1.8* 工程名:algorithm-core-le
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 一、父子类变量名相同会咋样? 有个小故事,今天群里面有个人问下面如图输出什么? 我回答:60。但这是错的,答案结果是 40 。我知错能改,然后说了下父子类变
作者:泥瓦匠 出处:https://www.bysocket.com/2021-10-26/mac-create-files-from-the-root-directory.html Mac 操作系统挺适合开发者进行写代码,最近碰到了一个问题,问题是如何在 macOS 根目录创建文件夹。不同的 ma
作者:李强强上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。一、引子在Java世界里,99%的工作都是处理这高层。那么二进制,字节码这些会在哪里用到呢?自问自答:在跨平台的时候,就凸显神功了。比如说文件读写,数据通信,还
1 线程中断 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want需求 项目在设计表的时候,要处理并发多的一些数据,类似订单号不能重复,要保持唯一。原本以为来个时间戳,精确到毫秒应该不错了。后来觉得是错了,测试环境下很多一
纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 加微信:bysocket01
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want.文章Points:1、介绍RESTful架构风格2、Spring配置CXF3、三层初设计,实现WebService接口层4、撰写HTTPClient 客户
Writer :BYSocket(泥沙砖瓦浆木匠)什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道“就一个回调…”。此时千万个草泥马飞奔而过(逃哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉。不妨总结总结。一、什么是回调回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百
Writer :BYSocket(泥沙砖瓦浆木匠)一、什么大小端?大小端在计算机业界,Endian表示数据在存储器中的存放顺序。百度百科如下叙述之:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加
What is a programming language? Before introducing compilation and decompilation, let&#39;s briefly introduce the Programming Language. Programming la
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket泥瓦匠喜欢Java,文章总是扯扯Java。 I/O 基础,就是二进制,也就是Bit。一、Bit与二进制什么是Bit(位)呢?位是CPU
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocket一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标:专注很重要。专注Java 基础 + H5(学习) 其他操作系统,算法,数据结构当成课外书博览。有时候,就是那样你越是专注方面越