泛型的详细介绍

目录

装箱和拆箱

补充知识valueOf

泛型

难点(了解):

补充知识,数组没有继承关系:

泛型的上界:

1 继承类:

2.实现接口

泛型方法:


装箱和拆箱

由基础类型转为包装类型叫做装箱;由包装类型转为基础类型叫做拆箱;除了Integer和Character,外

泛型的详细介绍_第1张图片

二者的转换时隐式转换,系统会在编辑的时候自动调用方法进行转换;

显示转换如下:

泛型的详细介绍_第2张图片

同理不是仅有int 和Interger可以这么写,其他类型转换的显示转换语法也是这样的,只需要将Integer换成Character,Double等等,int转换为doublt,float等

补充知识valueOf

泛型的详细介绍_第3张图片

将整形变为Integer发生了装箱,因此查看Integer.valueOf的源码

泛型的详细介绍_第4张图片

可知当超出某个阈值(-128~127)的时候返回的是新对象;

泛型

我们直接用例子来引出会更好理解:

如果我们需要在类中创建一个可以包含任意类型的数组成员,那么我们会将数组定义成Object(但这样不仅无法统一数组类型,同时如果想使用数组成员还需要进行强转,很麻烦,这个叫做裸类型),但是我们想要这个数组要么都放int 要么都放String,此时就需要一个规范

泛型的详细介绍_第5张图片

当我们添加完泛型之后,他与源代码的区别:

泛型的详细介绍_第6张图片

当我们给一个类添加后,这类就变成了一个泛型类。

第二红线处,为什么要创建Object的对象然后再强转呢,原因是泛型不能被实例化,因此红线第一处的代码不是很合理只是骗过了编译;

第三处,泛型就可以作为一个类型,其类型的决定取决于实例化泛型类时所给的类型,例如MyMap<>中给的是String类型,那么T就代表String类型,给setArray传值的时候也必须传String类型,在实例化MyMap的时候,也就是第五处的<>可以不写类型。

好处:运用泛型后不需要强制类型转换,编译时自动类型转换和检查;

注意:<>中只能放引用类型不能放基础类型

泛型的详细介绍_第7张图片

<>可以同时放多个字母都行,通常用T和E

优化代码:

红线第一处的代码可以改为:Object array  = new Object();然后主要修改泛型类中的方法,将Object类型的数组进行强转即可(如对该方法中的返回值进行强转)。

难点(了解):

泛型是编译时的一种机制,意味着运行的时候不存在泛型这个概念;这是因为擦除机制,在运行的时候,泛型会被自动转换为Object

这个会报错,因为数组类型不能进行整体强转;

补充知识,数组没有继承关系:

数组是一种单独的数据类型,int[],double[],Object[]都是各自独立的数据类型,不同于String,Object数组不存在继承关系,因此无法将int[]类型的数组传给Object[]类型的数组;同时数组之间也不能进行强转;

泛型的详细介绍_第8张图片

泛型的详细介绍_第9张图片

泛型的上界:

1 继承类:

即泛型继承某个类那么,<>中传入的只能是该类或者该类的子类,如果没写默认继承Object;

泛型的详细介绍_第10张图片

如图,T继承了Number,Integer是Number的子类,但是String不是,因此会报错;另外,泛型写成T或者E没有区别

2.实现接口

当我们想用泛型类实现一个数组最大值的函数时

泛型的详细介绍_第11张图片

对象类型不能直接用大于号比较

因此我们要用compareTo来比较

泛型的详细介绍_第12张图片

当我们不用泛型去实现接口的时候,程序就会报错;

泛型的详细介绍_第13张图片

这种写法表示所传入类型的类已经实现了Comparable这个接口,如图当我们用泛型去实现了Comparable这个接口的时候,此时func函数中就可以用array去调用CompareTo,因为此时默认传入的类实现了CompareTo这个接口,同时在实例化这个泛型类的时候传入的也必须是已经实现CompareTo接口的类;Person类没有实现就报错了。

泛型的详细介绍_第14张图片

泛型的详细介绍_第15张图片

泛型方法:

泛型的详细介绍_第16张图片

即在方法前写入泛型,格式同泛型类一样,完整写是在调用方法的时候传如类型;如果把该方法设置成静态方法,那么<>放在static后面

泛型的详细介绍_第17张图片

你可能感兴趣的:(数据结构与算法,java,开发语言,数据结构)