Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:将集合类型强制转换为子类型_Java_Generics_Collections_Casting_Type Erasure - Fatal编程技术网

Java:将集合类型强制转换为子类型

Java:将集合类型强制转换为子类型,java,generics,collections,casting,type-erasure,Java,Generics,Collections,Casting,Type Erasure,假设类B扩展类A。我有一个列表,我碰巧知道它只包含B的实例。有没有办法将列表转换为列表 似乎我唯一的选择是迭代集合,一次转换一个元素,创建一个新集合。这似乎是对资源的完全浪费,因为类型擦除在运行时完全不需要这样做。代码>列表: 子类型不通过泛型类型扩展:T您可以通过非类型化列表界面强制转换: List<A> a = new ArrayList<A>(); List<B> b = (List)a; List a=new ArrayList(); 列表b=(列表

假设类
B
扩展类
A
。我有一个
列表
,我碰巧知道它只包含
B
的实例。有没有办法将
列表转换为
列表

似乎我唯一的选择是迭代集合,一次转换一个元素,创建一个新集合。这似乎是对资源的完全浪费,因为类型擦除在运行时完全不需要这样做。

代码>列表:


子类型不通过泛型类型扩展:
T您可以通过非类型化列表界面强制转换:

List<A> a = new ArrayList<A>();
List<B> b = (List)a;
List a=new ArrayList();
列表b=(列表)a;
您可以尝试以下方法:

List<A> a = new ArrayList<A>();
List<B> b = (List<B>) (List<?>) a;
List a=new ArrayList();
列表b=(列表)(列表)a;

它基于jarnbjo的答案,但基于“不要使用原始列表”。

保持某种类型安全性并将对性能的影响降至最低的一种方法是使用。这个例子是关于收集的,列表的情况非常相似,也许有一天我也会写这个。如果有人在我前面,请让我们分享代码。

并在过程中解除所有类型安全!如果
A
B
的基类,则列表可以包含
A
,而处理
B
的代码希望它只返回
B
对象。这就是为什么这个案子一开始就不被允许的原因。@Joachim,我想这就是最初问题的重点。与传统强制转换方法相比,这种方法的唯一缺点是,如果你错了,错误将在很久以后才会出现,并且更难找到,而迭代会暴露你的错误。@Joachim-你正在失去类型安全性;编译器无法保证列表确实是一个列表,这就是为什么它不允许您首先执行强制转换的原因。如果您自己断言它,这很好,但这不是静态类型安全的。只要他只使用结果列表来检索元素而不插入它们(例如,这可能会触发运行时检查
checkedList
),他就应该没事了。Pavel拥有它。这个问题的条件是,他已经确信它只有B的实例。没有这个条件,这个问题就没有意义了。谢谢大家的好答案。在这种情况下,强制转换到列表是最合适的解决方案。在这种情况下,我愿意牺牲类型安全性来换取性能。依情况而定。在运行时,由于类型擦除,
List
变为
List
List
变为
List
,因此您的语句在运行时是错误的,因为
List
List
@pkk的子类型(如in可从中赋值):这仅适用于纯粹从JVM的角度来看类型系统。泛型几乎完全是一种语言级别的构造,因此JVM对它知之甚少甚至一无所知(这就是我同意你的观点的地方)。但是泛型的全部要点是,它们可以与遗留代码结合使用,如果编译器不发出警告,它们的保证将成立。通过转换原始类型(即执行JVM无论如何都会执行的操作)破坏了类型系统,从而破坏了泛型的目的。然而,我仍然想知道,为什么在语法层面上,以下含义不成立(即,没有在语言层面上实现,IMO应该实现):
Foo是Foo的一个子类型,只有当a是B的一个子类型时。
才能解决上述问题(也可能与Java中使用的泛型有关。@pkk:A
Foo
可能意味着两件事:它接受所有
A
,或者它只返回
A
(或者两者,甚至可能在同一个方法中)。对于“它接受所有
A
”(例如,作为方法参数),您的建议将成立。但是对于“它只返回
A
”它不会:A
Foo
不会返回
B
(当然可以,但不能保证)。