编程语言
首页 > 编程语言> > 为什么在Java中从List中删除原始类型时没有Autoboxing?

为什么在Java中从List中删除原始类型时没有Autoboxing?

作者:互联网

我有以下代码抛出IndexOutOfBoundsException异常:

 List<Character> list = new ArrayList<>();
 char c  = 'a';
 list.add(c);
 list.remove(c); // gets fixed by passing list.remove((Character)c);

我知道发生这种情况是因为在移除时不会发生AutoBoxing,而在添加元素时会发生AutoBoxing.我的问题是为什么?添加从char到Character的AutoBoxing是可行的,而在remove方法中它不是吗?

解决方法:

Java会考虑将基本类型装入包装类型,但前提是它还没有考虑过不需要打包参数的重载方法.

JLS, Section 15.12.2,涵盖哪个过载选择如下:

  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object…) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.

(大胆的重点是我的)

  1. The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.

  1. The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

编译器看不到任何其他可能与add(Character)匹配的add的重载,所以它在第二阶段考虑装箱并找到它的匹配.

但是,编译器确实看到了匹配的重载,没有装箱,remove(int),因此char被扩展为int.编译器在第一阶段找到了它的方法,因此从未考虑过第二阶段.
 正如您所知,这会强制您将char显式转换为Character以获得匹配的正确方法.

这恰好是在Java 5中引入装箱和拆箱导致在该版本之前不存在的歧义的情况.如果这些方法名称的设计考虑到这一点,设计者很可能会使用不同的方法名称,避免过载和这种模糊性.

标签:java,autoboxing,list
来源: https://codeday.me/bug/20190717/1486368.html