java 安全数组_关于java:如何安全地从泛型类型的集合转换为数组?

本问题已经有最佳答案,请猛点这里访问。

出于各种原因,我希望将列表转换为数组,但是集合包含本身是泛型的对象。

我尝试了以下四个选项来编译它,而不需要@supressWarnings("unchecked")注释,但它们都不起作用。是否有解决方案可以使此正确工作,或者强制使用注释?

Iterator[] iterators;

final Collection> initIterators = new ArrayList>();

// Type safety: Unchecked cast from Iterator[] to Iterator[]

iterators = initIterators.>toArray(

(Iterator[])new Iterator[initIterators.size()]);

// Type safety: Unchecked invocation toArray(Iterator[]) of the generic

// method toArray(T[]) of type Collection>

// Type safety: The expression of type Iterator[] needs unchecked conversion

// to conform to Iterator[]

iterators = initIterators.>toArray(

new Iterator[initIterators.size()]);

// Type safety: The expression of type Iterator[] needs unchecked conversion

// to conform to Iterator[]

iterators = initIterators.toArray(new Iterator[initIterators.size()]);

// Doesn't compile

iterators = initIterators.toArray(new Iterator[initIterators.size()]);

也许[这]会有所帮助。不管怎样,我也很感兴趣为什么有人想要使用数组(不支持泛型)而不是数组列表。

泛型列表数组可能重复。另请参见:具有多个子级的树的数组中的泛型类型。

@我认为你列出的问题并不是重复的,尽管他们谈论的是类似的材料。

@pshemo这是处理一些需要数组的遗留代码所必需的。一些新的代码会绕过列表,在进行泛型之前,它们可以在两个代码之间进行转换而不受惩罚。当然,我仍然可以,我只是想摆脱警告,而不压制它。

重复的选择往往不是因为问题本身完全相同,而是因为它们的答案提供了相同的解决方案。我知道这可能马上就不合理了,我花了一段时间才习惯。但是无论如何,如果你使用Java 7,你应该在链接的帖子上签出这个答案。我链接到第二篇文章,不是因为它是重复的,而是因为我在那里的回答谈到了为什么存在这个编译器限制。

@ @ PaulWagland如果您的继承代码期望的是一个5到0个字节,那么Java + +"泛型"版本的版本是1和两个兼容。请注意,数组将允许任何Iterator作为元素,因此如果旧代码返回给您一个Iterator[],那么您就不能(从编译器的角度)安全地将元素强制转换回Iterator。如果您绝对确信遗留代码不会混合不同类型的迭代器,那么这就是@SuppressWarnings("unchecked")注释存在的原因。仅与旧代码一起使用。

没有类型安全的方法来创建参数化类型的数组,如Iterator[]。

或者,您可以创建一个原始数组:Iterator>[]。或者,如果可以完全避免使用数组,请使用像List>这样的集合类型。

不可能的原因是Java数组是协变的,泛型类型的参数化边界是不变的。这就是说:

Integer[] integers = new Integer[1];

Number[] numbers = integers; // OK because Integer extends Number

numbers[0] = new Double(3.14); // runtime exception

由于Double扩展了Number,并且声明的numbers类型是Number[],因此编译器允许赋值。但在运行时,实际的数组对象实例是原始的Integer[1],数组知道它们包含的对象的类型。

对于泛型,参数化类型是不同的。首先,由于编译时类型擦除,它们本质上不知道自己的运行时类型。

List integerList = new ArrayList();

List numberList = integerList; // compiler error, prevents:

numberList.add(new Double(3.14)); // would insert a Double into integerList

Collection integerCollection = integerList; // allowed

// OK because List extends Collection and the did not change

Collection numberCollection = integerList; // compiler error

// an"Integer" is a"Number"

// but"a collection of Integers" is more specific than"a collection of Numbers"

// and cannot be generally treated the same way and guarantee correct behavior

List> rawList = integerList; // allowed, but...

rawList.add(new Integer(42));  // compiler error, Integer is not a ... a what?

对于泛型,在Java中,您依赖编译器(而不是运行时)来验证泛型类型是否正确和安全。

因此,虽然Iterator>[]在运行时知道它是一个包含Iterator元素的数组,但Iterator[]中的在编译时被删除,运行时无法知道它应该是什么。所以你会得到一个未选中的警告。

+一个很好的解释。

很好的解释,但不幸的是,这对我没有帮助。我有一个集合,但我需要一个迭代器。我想将前者转换为后者,我可以这样做,但不能没有编译器警告。我只想消除这个警告。

@paulwagland:在任何情况下都不可能得到Iterator[]类型的非null值,而不抑制某个地方的警告(无论是在代码中还是在您调用的某个函数中)。

@纽阿克特很有帮助,但这不是我想要的答案;-)但我害怕的是这个答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值