【问题标题】:Integer and int duality?整数和整数对偶?
【发布时间】:2011-05-25 18:55:59
【问题描述】:

谁能解释一下这个

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

我用的时候

 list.remove(1);

然后第一个元素被删除

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

然后第二个元素被删除。

那么,你能解释一下上述场景中自动装箱和拆箱的行为吗

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 被执行

【问题讨论】:

    标签: java


    【解决方案1】:

    当出现Integer 参数时,重载决议基本上会优先使用Object 参数而不是int 参数。 (当然,当带有int 参数时,它会更喜欢带有int 参数的重载而不是ObjectInteger。)

    来自JLS section 15.12.2(讨论被剪断):

    确定适用性的过程从确定可能适用的方法开始(第 15.12.2.1 节)。该过程的其余部分分为三个阶段。

    讨论

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

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

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

    第三阶段(第 15.12.2.4 节)允许将重载与可变参数方法、装箱和拆箱相结合。

    由于Integer 可以隐式转换为Object,因此重载解析在第一阶段成功,因此永远不会考虑拆箱转换。

    如果这不能让您满意地解释一切,请评论您仍然困惑的部分。

    【讨论】:

      【解决方案2】:
       list.remove(1);
      

      这里 1 是索引,而不是对象,所以索引 1 处存在的任何对象都将被删除

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

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

      【讨论】:

        【解决方案3】:

        这一切都在 Java Language Specification 中进行了解释和说明。

        【讨论】:

          【解决方案4】:

          问题是 new Integer(2) 是一个对象,但 2 不是

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

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

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

          在您的第二个示例中可能会发生同样的情况,尽管它似乎有点混淆(文本不适合代码)。

          关键部分是:Integer的拆箱只有在Integer不能使用的情况下进行,即Integer、Number或Object都没有用,但是int可以使用。

          【讨论】:

            【解决方案5】:

            重载解决方案使用最佳匹配候选。在第一种情况下,您传递的是 Integer 并且有一个签名 test(Integer) 以便被调用(精确类型匹配)。

            在第二种情况下,您通过 Integer,两个可能的候选者是 test(int) 和 test(Object)。在这种情况下,语言将 Object 向上转换定义为比 int 拆箱更接近,因此选择了对象版本。

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

            【讨论】:

              【解决方案6】:

              来自Java language specification

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

              ...

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

              【讨论】:

                【解决方案7】:

                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)),那么这个调用的最佳匹配是第一个方法(删除对象)。

                【讨论】:

                  【解决方案8】:

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

                  虽然 Java 确实执行了自动装箱(如果 List.remove(int) 方法不存在,我相信它会执行),这里的想法是确定调用哪个方法。由于有一个带有原始 int 的有效操作,因此将在任何自动装箱发生之前调用它。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2013-04-22
                    • 1970-01-01
                    • 2014-06-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-12-26
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多