整数和整数二元性?

时间:2011-05-25 10:48:06

标签: java

有人可以解释一下这个

 List<Integer> list = new LinkedList<Integer>();
 list.add(2);
 list.add(1);
 list.add(3);

当我使用

 list.remove(1);

然后第一个元素被删除

 list.remove(new Integer("1"));

然后第二个元素被移除。

所以,你能解释上面的Senario中自动装箱和拆箱的行为吗?

new A().a(new Integer("1"));

执行,

public class A {
    public void test(Integer i) {} //1
    public void test(int i) {} //2
    public void test(Object o) {}//3
} 

方法1执行

public class A {
    public void test(int i) {} //2
    public void test(Object o) {}//3
} 

方法3已执行

8 个答案:

答案 0 :(得分:2)

基本上,当出现Object参数时,重载决策将优先于int参数而不是Integer参数。 (当然,当出现int参数时,它会偏好Object参数超过Integerint。)

来自JLS section 15.12.2(讨论已删除):

确定适用性的过程首先确定可能适用的方法(§15.12.2.1)。该过程的其余部分分为三个阶段。

讨论

分阶段的目的是确保与旧版本的Java编程语言兼容。

  

第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。

     

第二阶段(§15.12.2.3)在允许装箱和拆箱的同时执行重载解析,但仍然排除使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。

     

第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合。

由于Integer可隐式转换为Object,因此重载解析在第一阶段成功,因此从未考虑到取消装箱转换。

如果这并不能解释您满意的一切,请评论哪一点仍然令您感到困惑。

答案 1 :(得分:1)

 list.remove(1);

此处1是索引,而不是对象,因此索引1处的任何对象都将被删除

 list.remove(new Integer("1"));

这里是对象Integer(1),将被删除

答案 2 :(得分:0)

这一切都在Java Language Specification中解释和指定。

答案 3 :(得分:0)

问题是新的Integer(2)是一个对象但是2不是

remove(1)删除索引为1的元素

remove(new Integer(2)删除Objecte等于new Integer(2)(两种不同的方法)

如果添加(1)Java需要一个对象,因为没有add(int)并执行Outboxing。

同样的情况可能发生在你的第二个例子中,虽然它看起来有点混乱(文本不适合代码)。

关键部分是:只有在不能使用Integer时才会执行Intebox的Unboxing,即不使用Integer,Number或Object,但可以使用int。

答案 4 :(得分:0)

重载分辨率使用最佳匹配候选。在第一种情况下,您传递的是Integer,并且有一个签名测试(Integer),以便调用(精确类型匹配)。

在第二种情况下,您传递Integer,两个可能的候选者是test(int)和test(Object)。在这种情况下,语言将Object upcast定义为比int拆箱更接近的匹配,因此选择了Object版本。

有一个重载决策转换列表here。如您所见,参考扩展比拆箱更高。

答案 5 :(得分:0)

来自Java language specification

  

第一阶段(§15.12.2.2)执行   不允许的重载决议   装箱或拆箱转换,

     

...

     

这可以保证任何调用   在旧版本中有效   语言不被认为是模棱两可的   由于引入   变量arity方法,隐含   装箱和/或拆箱。

答案 6 :(得分:0)

List提供方法:

public boolean remove(Object o)   // removes the first occurence of this object
public boolean remove(int i)      // removes object stored at index i

如果我们执行list.remove(new Integer(1)),则此调用的最佳匹配是第一种方法(删除对象)。

答案 7 :(得分:0)

List上指定了两个删除函数:

尽管Java确实执行了自动装箱(我相信如果List.remove(int)方法不存在),这里的想法是确定调用哪种方法。由于存在基元int的有效操作,因此在任何自动装箱发生之前都会调用它。