ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-07-17 08:04:10  阅读:223  来源: 互联网

标签:java autoboxing list


我有以下代码抛出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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有