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

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

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

目录

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对象都可以添加进去,但是要使用的时候忘了添加过什么类型的对象进去,根据提示强转过,但是由于添加进去一些类型不同的,强转可以在编译时通过,运行时异常抛出了。

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

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

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

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

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

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

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)不同泛型之间不能相互赋值,举例

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

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

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

另外这里报错原因是: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 由于泛型擦除出现的错误举例:

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

 报错原因: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.net/180164.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Linux基礎知識 —— open&close

    Linux基礎知識 —— open&close

    2022年2月21日
    47
  • 再谈肥六之应用软件

    再谈肥六之应用软件1、系统管理:SmartFileman和SeleQ。后者自不多说,是S60平台上的经典软件,界面亲和、功能强大;后者Fileman是我现在所用的系统管理软件,个人觉得此款软件更顺手些——打开软件后便可以清楚显示手机各盘的存储情况(剩余空间/总空间)、功能一应俱全、图标清晰形象……总之,个人比较偏爱于Fileman。  2、内存管理:APPMAN。功能极为强大,能够显示当前系统资源的利用情…

    2022年7月11日
    15
  • python实现交叉验证_kfold显示不可迭代

    python实现交叉验证_kfold显示不可迭代KFold模块fromsklearn.model_selectionimportKFold为什么要使用交叉验证?交叉验证的介绍交叉验证是在机器学习建立模型和验证模型参数时常用的办法。交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在…

    2022年9月20日
    0
  • Mac 卸载Java「建议收藏」

    Mac 卸载Java「建议收藏」Mac彻底卸载Javamac上终端安装了太多的JavaJDK版本,计划全部删除,重新安装最新版本JDK。打开终端输入以下命令://1、移除JavaAppletPlugin.plugin与JavaControlPanel.prefpanesudorm-fr/Library/Internet\Plug-Ins/JavaAppletPlugin.pluginsudorm-fr/Library/PreferencesPanes/JavaControlPanel.prefpane

    2022年5月19日
    80
  • VIF检验相关性「建议收藏」

    VIF检验相关性「建议收藏」VIF可以用来度量多重共线性问题,VIFj=11−Rj2\quad\mathrm{VIF}_{j}=\frac{1}{1-R_{j}^{2}}VIFj​=1−Rj2​1​式子中,Rj2R_{j}^{2}Rj2​是第jjj个变量在所有变量上回归时的确定系数。如果VIF过大(比如大于5或10),则意味着存在多重共线性问题。#数据df=pd.read_excel(io=’数据.xlsx’,sheet_name=0,usecols=range(1,5))#务必注意:一定要加上常数项,#如果没

    2022年4月28日
    138
  • vim命令大全(转)[通俗易懂]

    vim命令大全(转)[通俗易懂]命令历史以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令。启动vim在命令行窗口中输入以下命令即可vim直接启动vimvimfilename打开vim并创建名为filename的文件文件命令打开单个文件vimfile同时打开多个文件vimfile1file2file3…在vim窗口中打开一个…

    2022年5月30日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号