栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

通过未经检查的类型转换在Java中创建通用数组

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

通过未经检查的类型转换在Java中创建通用数组

自从我在问题中被提及以来,我会插话。

基本上,如果不将此数组变量暴露给类的外部对象,则不会造成任何问题。(有点像,在拉斯维加斯发生的事情留在拉斯维加斯。)

数组的实际运行时类型为

Object[]
。因此将其放入类型变量
Bar[]
实际上是一个“谎言”,因为
Object[]
它不是
Bar[]
(除非
Object
Bar
)的子类型。但是,如果该谎言停留在班级内部,则可以,因为它
Bar
已被删除到
Object
班级内部。(下界的
Bar
Object
在这个问题上,在下界的情况
Bar
是另一回事,更换所有出现
Object
在这次讨论与任何该界是。)但是,如果这个谎言被莫名其妙地暴露于外(最简单的示例
bars
直接将变量作为type
返回
Bar[]
,则将导致问题。

要了解实际情况,有和没有泛型的代码都具有启发性。只需删除泛型并在正确的位置插入强制类型转换,即可将任何泛型程序重写为等效的非泛型程序。这种转换称为
类型擦除

我们考虑使用的简单实现

Foo<Bar>
,其中包含用于获取和设置数组中特定元素的方法,以及用于获取整个数组的方法:

class Foo<Bar> {    Bar[] bars = (Bar[])new Object[5];    public Bar get(int i) {        return bars[i];    }    public void set(int i, Bar x) {        bars[i] = x;    }    public Bar[] getArray() {        return bars;    }}// in some method somewhere:Foo<String> foo = new Foo<String>();foo.set(2, "hello");String other = foo.get(3);String[] allStrings = foo.getArray();

类型擦除后,将变为:

class Foo {    Object[] bars = new Object[5];    public Object get(int i) {        return bars[i];    }    public void set(int i, Object x) {        bars[i] = x;    }    public Object[] getArray() {        return bars;    }}// in some method somewhere:Foo foo = new Foo();foo.set(2, "hello");String other = (String)foo.get(3);String[] allStrings = (String[])foo.getArray();

因此,班级内不再有演员表。但是,在调用代码中有强制转换-
当获取一个元素并获取整个数组时。获得一个元素的强制转换应该不会失败,因为我们只能放入数组中

Bar
,所以我们唯一也可以取出
Bar
。但是,由于数组具有实际的运行时类型,因此在获取整个数组时进行强制转换将失败
Object[]

非一般性地写,正在发生的事情和问题变得更加明显。尤其令人困扰的是,强制转换失败不会发生在我们使用泛型编写强制转换的类中,而是发生在使用我们类的其他人的代码中。该其他人的代码是完全安全无辜的。当我们在泛型代码中进行转换时,也不会发生这种情况,而是稍后有人在

getArray()
没有警告的情况下调用它。

如果我们没有此

getArray()
方法,则此类将是安全的。用这种方法,是不安全的。什么特征使其不安全?它
bars
以type
返回
Bar[]
,这取决于我们之前所做的“谎言”。由于谎言不是真的,因此会引起问题。如果该方法改为将数组返回为type
Object[]
,那么它将是安全的,因为它不依赖于“ lie”。

人们会告诉您不要像这样进行强制转换,因为它会导致意外异常(如上所示),而不是未经检查的强制转换的原始位置,导致强制转换异常。编译器不会警告您这

getArray()
是不安全的(因为从它的角度来看,给定您所告诉的类型,它是安全的)。因此,这取决于程序员对这种陷阱的勤奋工作,而不是以不安全的方式使用它。

但是,我认为这在实践中并不是一个大问题。任何设计良好的API都不会将内部实例变量暴露给外部。(即使有一种方法将内容作为数组返回,它也不会直接返回内部变量;而是会复制它,以防止外部代码直接修改该数组。)因此,

getArray()
无论如何都不会实现任何方法。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/495983.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号