下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】抖音二面栽在泛型擦除?答应我,别和我倒在同一地方!
这是我在抖音二面的时候自我感觉没有答好的一题。因为我的中心只是围绕在了
T被
Object替换的问题上了,并没有去讲解他会带来的问题。其实我们很常见这个问题,你甚至经常用,只是没有去注意罢了,但是很不碰巧这样的问题就容易被面试官抓住。下面先来看一段代码吧。
List
list
=
new
ArrayList();
List
listString
=
new
ArrayList<String>();
List
listInteger
=
new
ArrayList<Integer>();这几段代码简单、粗暴、又带有很浓厚的熟悉感是吧。那我接下来要把一个
数字1插入到这三段不一样的代码中了。作为读者的你可能现在已经黑人问号了????你肯定有很多疑问,这明显不一样啊,怎么可能。
public
class
Main
{
public
static
void
main(String[]
args)
{
List
list
=
new
ArrayList();
List
listString
=
new
ArrayList<String>();
List
listInteger
=
new
ArrayList<Integer>();
try
{
list.getClass().getMethod("add",
Object.class).invoke(list,
1);
listString.getClass().getMethod("add",
Object.class).invoke(listString,
1);
//
给不服气的读者们的测试之处,你可以改成字符串来尝试。
listInteger.getClass().getMethod("add",
Object.class).invoke(listInteger,
1);
}
catch
(Exception
e)
{
e.printStackTrace();
}
System.out.println("list
size:"
+
list.size());
System.out.println("listString
size:"
+
listString.size());
System.out.println("listInteger
size:"
+
listInteger.size());
}
}不好意思,有图有真相,我就是插进去了,要是你还不信,我还真没办法了。探索真相上述的就是泛型擦除的一种表现了,但是为了更好的理解,当然要更深入了是吧。虽然
List很大,但却也不是不能看看。两个关键点,来验证一下:
//
先来看看画了一个大饼的List
//
能够过很清楚的看到泛型E
public
class
ArrayList<E>
extends
AbstractList<E>
implements
List<E>,
RandomAccess,
Cloneable,
java.io.Serializable{
//
第一个关键点
//
还没开始就出问题的存储类型
//
难道不应该也是一个泛型E?
transient
Object[]
elementData;
public
E
get(int
index)
{
rangeCheck(index);
return
elementData(index);
//
1>
}
//
由1直接调用的函数
//
第二个关键点,强制转化得来的数据
E
elementData(int
index)
{
return
(E)
elementData[index];
}
}我想,其实你也能够懂了,这个所谓的泛型
T最后会被转化为一个
Object,最后又通过强制转化来进行一个转变。从这里我们也就能够知道为什么我们的数据从前面过来的时候,
String类型数据能够直接被
Integer进行接收了。
(1)强制类型转化这个问题的结果我们已经在上述文章中提及到了,通过反射的方式去进行插入的时候,我们的数据就会发生错误。如果我们在一个
List<Integer>中在不知情的情况下插入了一个
String类型的数值,那这种重大错误,我们该找谁去说呢。
(2)引用传递问题上面的问题中,我们已经说过了
T将在后期被转义成
Object,那我们对引用也进行一个转化,是否行得通呢?
List<String>
listObject
=
new
ArrayList<Object>();
List<Object>
listObject
=
new
ArrayList<String>();如果你这样写,在我们的检查阶段,会报错。但是从逻辑意义上来说,其实你真的有错吗?
假设说我们的第一种方案是正确的,那么其实就是将一堆
Object数据存入,然后再由上面所说的强制转化一般,转化成
String类型,听起来完全ok,因为在
List中本来存储数据的方式就是
Object。但其实是会出现
ClassCastException的问题,因为
Object是万物的基类,但是强转是为子类向父类准备的措施。
再来假设说我们的第二种方案是正确的,这个时候,根据上方的数据
String存入,但是有什么意义存在呢?最后都还是要成
Object的,你还不如就直接是
Object。其实很简单,如果看过一些公开课想来就见过这样的用法。
public
class
Part<T
extends
Parent>
{
private
T
val;
public
T
getVal()
{
return
val;
}
public
void
setVal(T
val)
{
this.val
=
val;
}
}相比较于之前的
Part而言,他多了
<TextendsParent>的语句,其实这就是将基类重新规划的操作,就算被编译,虚拟机也会知道将数据转化为
Parent而不是直接用
Object来直接进行替代。
这里需要感谢给我提出问题的大佬读者:挖掘机技术
该部分的思路来自于
Java泛型中extends和super的区别?这里需要感谢给我提出问题的大佬读者:挖掘机技术该部分的思路来自于
Java泛型中extends和super的区别?上面我们说过了解决方案,使用
<TextendsParent>。其实这只是一种方案,在不同的场景下,我们需要加入不同的使用方法。另外官方也是提倡使用这样的方法的,但是我们为了避免我们上述的错误,自然需要给出一些使用场景了。基于的其实是两种场景,一个是扩展型
super,一个是继承型
extends。下面都用一个列表来举例子。统一继承顺序
//
承载者
class
Plate<T>{
private
T
item;
public
Plate(T
t){item=t;}
public
void
set(T
t){item=t;}
public
T
get(){return
item;}
}
//
Lev
1
class
Food{}
//
Lev
2
class
Fruit
extends
Food{}
class
Meat
extends
Food{}
//Lev
3
class
Apple
extends
Fruit{}
class
Banana
extends
Fruit{}
class
Pork
extends
Meat{}
class
Beef
extends
Meat{}
//Lev
4
class
RedApple
extends
Apple{}
class
GreenApple
extends
Apple{}
<TextendsParent>继承型的用处是什么呢?其实他期待的就是这整个列表的数据的基础都是来自我们的
Parent,这样获取的数据全部人的父类其实都是来自于我们的
Parent了,你可以叫这个列表为
Parent家族。所以也可以说这是一个适合频繁读取的方案。
Plate<?
extends
Fruit>
p1=new
Plate<Apple>(new
Apple());
Plate<?
extends
Fruit>
p2=new
Plate<Apple>(new
Beef());
//
检查不通过
//
修改数据不通过
p1.set(new
Banana());
//
数据获取一切正常
//
但是他只能精确到由我们定义的Fruit
Fruit
result
=
p1.get();
<TsuperParent>扩展型的作用是什么呢?你可以把它当成一种兼容工具,由
super修饰,说明兼容这个类,通过这样的方式比较适用于去存放上面所说的
Parent列表中的数据。这是一个适合频繁插入的方案。
//
填写Food的位置,级别一定要大于或等于Fruit
Plate<?
super
Fruit>
p1=new
Plate<Food>(new
Apple());
//
和extends
不同可以进行存储
p1.set(new
Banana());
//
get方法
Banana
result1
=
p1.get();
//
会报错,一定要经过强制转化,因为返回的只是一个Object
Object
result2
=
p1.get();
//
返回一个Object数据我们已经属于快要丢失掉全部数据了,所以不适合读取
以上就是我的学习成果,如果有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。以上就是我的学习成果,如果有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。附上我的Android核心技术学习大纲,获取相关内容来我的GitHub一起玩耍:
/Meng997998/AndroidJX
vx:xx1341452对于进阶这条路而言,学习是会有回报的!你把你的时间投资在学习上,就意味着你
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2030年全球及中国钐行业发展状况及应用趋势预测报告
- 2024-2030年全球及中国熔融碳酸盐燃料电池行业需求趋势及投资前景展望报告版
- 2024-2030年全球及中国光学聚酯薄膜行业产销规模与应用趋势预测研究报告
- 建设项目安全管理体系标准
- 大数据应用下的加盟连锁精准营销
- 客房营销方案设计案例分析报告
- 幼儿园主题方案设计疑问
- 电缆材料与制造优化
- 基因探针检测原理及应用
- 基因组学在溃疡性结肠炎诊断和治疗中的作用
- 2023年广东省茂名市茂南区茂南开发区社区工作人员考试模拟题及答案
- 马工程《刑法学(下册)》教学课件 第19章 破坏社会主义市场经济秩序罪
- GB/T 10001.6-2021公共信息图形符号第6部分:医疗保健符号
- 随班就读教学设计模版
- 英语专业四级考试写作课件
- “快乐学习、塑造自我”教案-高中主题班会
- 互联网+拍卖云平台建设项目解决方案
- 《拟行路难》课件26张
- 土地确权与土地权属争议调处政策课件
- 2023年中考生物模拟试卷(含答案)
- 《感染性腹泻》课件
评论
0/150
提交评论