Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >泛型(泛型擦除)【java基础—-泛型】

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

作者头像
全栈程序员站长
发布于 2022-11-02 09:18:26
发布于 2022-11-02 09:18:26
3.1K00
代码可运行
举报
运行总次数:0
代码可运行

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

目录 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 泛型定义(泛型类、泛型方法(泛型方法返回值是泛型的,泛型方法在普通类和泛型类里)):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
10、泛型的定义是<T>(带尖角号的T),
例如定义一个泛型类:public class Stu<T>{ }
定义一个泛型方法(不在泛型类里):publilc <T> void testMethod() { }
或定义一个返回值类型是泛型的方法(不在泛型类里): public <T> T testMethod2(){return null}
注意,(在泛型类里 的返回值是泛型的方法)在定义了泛型类之后,在该类里想要返回值类型是一个泛型的方法(),
不用再<T>定义该方法是泛型啦,直接可以使用泛型的Tpublic T testMethod3(){return null}

1.4特点:

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面试系列之-JAVA泛型剖析(JAVA基础)
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参列表,普通方法的形参列表中,每个形参的数据类型是确定的,而变量是一个参数。在调用普通方法时需要传入对应形参数据类型的变量(实参),若传入的实参与形参定义的数据类型不匹配,则会报错。
用户4283147
2023/08/21
4390
面试系列之-JAVA泛型剖析(JAVA基础)
【Java 基础 - 泛型机制详细解释】
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
奥耶可乐冰
2023/11/29
5820
【Java 基础 - 泛型机制详细解释】
Java基础篇:泛型与类型擦除
泛型的本质是 参数化类型,也就是说 将所操作的数据类型 指定为一个参数,在不创建新类的情况下,通过参数来指定所要操作的具体类型(类似于方法中的变量参数,此时类型也定义成参数形式),也就是说,在创建对象或者调用方法的时候才明确下具体的类型。可以在类、接口、方法中使用,分别称为泛型类、泛型接口、泛型方法。
全栈程序员站长
2021/12/23
1.2K0
Java基础篇:泛型与类型擦除
带你深挖Java泛型类型擦除以及类型擦除带来的问题
大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。
业余草
2020/02/13
1.8K0
Java基础(一) 泛型
泛型概念 本质是参数化类型,把类型作为参数传递。 常见形式有泛型类、泛型接口、泛型方法。 语法 T成为类型占位符,表示一种引用类型,可以写多个逗号隔开。 好处 1. 提高代码重用性 2. 防止类型转换异常,提高代码安全性。 最近介绍泛型集合。 泛型类 // 写一个泛型类。 public class MyGeneric<T>{ //使用泛型T。 //1 创建变量。 T t; //2 泛型作为方法的参数。 public void show(T t){ sout(t); } /
宇宙无敌暴龙战士之心悦大王
2022/01/10
2340
Java 泛型:理解和应用
这就是泛型的概念,是 Java 后期的重大变化之一。泛型实现了参数化类型,可以适用于多种类型。泛型为 Java 的动态类型机制提供很好的补充,但是 Java 的泛型本质上是一种高级语法糖,也存在类型擦除导致的信息丢失等多种缺点,我们可以在本篇文章中深度探讨和分析。
phoenix.xiao
2023/08/28
2850
Java 泛型:理解和应用
深入理解 Java 泛型
泛型要求在声明时指定实际数据类型,Java 编译器在编译时会对泛型代码做强类型检查,并在代码违反类型安全时发出告警。早发现,早治理,把隐患扼杀于摇篮,在编译时发现并修复错误所付出的代价远比在运行时小。
静默虚空
2022/03/23
4420
深入理解 Java 泛型
Java泛型,你了解类型擦除吗?
大家可能会有疑问,我为什么叫做泛型是一个守门者。这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神奇。泛型是 Java 中一个很小巧的概念,但同时也是一个很容易让人迷惑的知识点,它让人迷惑的地方在于它的许多表现有点违反直觉。
Java团长
2018/08/03
2.3K0
Java泛型详解,史上最全图文详解「建议收藏」
毫不夸张的说,泛型是通用设计上必不可少的元素,所以真正理解与正确使用泛型,是一门必修课。
全栈程序员站长
2022/09/08
9650
Java 泛型深入解析:类型安全与灵活性的平衡
Java 泛型(Generics)是一个强大的语言特性,它允许在类、接口和方法中使用参数化类型,从而实现代码的重用、增强类型安全性,并提升代码的可读性。泛型的引入解决了 Java 编程中常见的类型转换问题,使得我们能够编写更加灵活且健壮的代码。然而,泛型背后的类型擦除(Type Erasure)机制和一些高级特性也给我们带来了一定的挑战。
科技新语
2024/10/11
1850
Java 泛型深入解析:类型安全与灵活性的平衡
精通Java,却不了解泛型?
在没有泛型的出现之前,我们通常是使用类型为 Object 的元素对象。比如我们可以构建一个类型为 Object 的集合,该集合能够存储任意数据类型的对象,但是我们从集合中取出元素的时候我们需要明确的知道存储每个元素的数据类型,这样才能进行元素转换,不然会出现 ClassCastException 异常。
蔡不菜丶
2020/12/10
5310
精通Java,却不了解泛型?
深入理解泛型
泛型(Generics)是Java编程语言中的一个特性,它允许在编译时提供类型检查并消除类型转换。Java中的泛型用于类、接口和方法的创建,它使得代码能够被不同的数据类型重用。
程序员朱永胜
2023/11/09
3270
关于对Java泛型的解释和思考
Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types while providing compile-time type safety".
互联网金融打杂
2022/08/01
6510
Java基础系列2:Java泛型
该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架。
说故事的五公子
2019/11/10
5680
Java - 泛型
参数化类型:把类型当作参数来传递,这意味着参数化类型不能是基本数据类型,需要用对应的包装类来代替。
雨临Lewis
2022/01/12
5950
Java泛型详解:为什么使用泛型?如何使用泛型?
大家好!今天我要和大家一起探讨的是Java泛型,一个让我们的代码更加灵活、可读性更强的强大特性。相信很多人都听说过泛型,但对于为什么使用泛型、如何使用泛型以及泛型的实现原理和本质,可能还有些困惑。别担心,我会通过通俗易懂的语言,带你深入了解这一话题,并为你提供一些实例演示。
默 语
2024/11/20
3720
【Java基础】JavaCore核心-泛型技术
互联网小阿祥
2023/05/28
3880
【Java基础】JavaCore核心-泛型技术
JAVA泛型与类型擦除
为什么要用T而不是其它字母?事实上是可以任意字符串(如Result< something >),但是为了显得专业,一般约定几个大写字母在不同场景使用。
acupt
2019/08/26
1.9K0
Java泛型深入理解「建议收藏」
在面向对象编程语言中,多态算是一种泛化机制。例如,你可以将方法的参数类型设置为基类,那么该方法就可以接受从这个基类中导出的任何类作为参数,这样的方法将会更具有通用性。此外,如果将方法参数声明为接口,将会更加灵活。
全栈程序员站长
2022/09/10
8920
带着问题高效学Android:关于Java与Kotlin泛型你应该知道的知识点
image.png 前言 带着问题学习可以让我们在学习的过程中更加有目的性与条理。 例如在读源码的过程中,我们如果从头开始读,往往千头万绪,抓不住要领。 而如果在开始读之前先带着几个问题,则可以让我们
Android技术干货分享
2020/11/17
1.2K0
带着问题高效学Android:关于Java与Kotlin泛型你应该知道的知识点
相关推荐
面试系列之-JAVA泛型剖析(JAVA基础)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验