<legend id='VNJ5H'><style id='VNJ5H'><dir id='VNJ5H'><q id='VNJ5H'></q></dir></style></legend>

      <small id='VNJ5H'></small><noframes id='VNJ5H'>

    1. <i id='VNJ5H'><tr id='VNJ5H'><dt id='VNJ5H'><q id='VNJ5H'><span id='VNJ5H'><b id='VNJ5H'><form id='VNJ5H'><ins id='VNJ5H'></ins><ul id='VNJ5H'></ul><sub id='VNJ5H'></sub></form><legend id='VNJ5H'></legend><bdo id='VNJ5H'><pre id='VNJ5H'><center id='VNJ5H'></center></pre></bdo></b><th id='VNJ5H'></th></span></q></dt></tr></i><div id='VNJ5H'><tfoot id='VNJ5H'></tfoot><dl id='VNJ5H'><fieldset id='VNJ5H'></fieldset></dl></div>

        <tfoot id='VNJ5H'></tfoot>
          <bdo id='VNJ5H'></bdo><ul id='VNJ5H'></ul>

        为什么自动装箱会使 Java 中的某些调用模棱两可?

        Why does autoboxing make some calls ambiguous in Java?(为什么自动装箱会使 Java 中的某些调用模棱两可?)
        • <bdo id='QMJuy'></bdo><ul id='QMJuy'></ul>

            <legend id='QMJuy'><style id='QMJuy'><dir id='QMJuy'><q id='QMJuy'></q></dir></style></legend>
              <tbody id='QMJuy'></tbody>

              <small id='QMJuy'></small><noframes id='QMJuy'>

              <tfoot id='QMJuy'></tfoot>

              <i id='QMJuy'><tr id='QMJuy'><dt id='QMJuy'><q id='QMJuy'><span id='QMJuy'><b id='QMJuy'><form id='QMJuy'><ins id='QMJuy'></ins><ul id='QMJuy'></ul><sub id='QMJuy'></sub></form><legend id='QMJuy'></legend><bdo id='QMJuy'><pre id='QMJuy'><center id='QMJuy'></center></pre></bdo></b><th id='QMJuy'></th></span></q></dt></tr></i><div id='QMJuy'><tfoot id='QMJuy'></tfoot><dl id='QMJuy'><fieldset id='QMJuy'></fieldset></dl></div>

                1. 本文介绍了为什么自动装箱会使 Java 中的某些调用模棱两可?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我今天注意到自动装箱有时会导致方法重载解决方案的歧义.最简单的例子似乎是这样的:

                  I noticed today that auto-boxing can sometimes cause ambiguity in method overload resolution. The simplest example appears to be this:

                  public class Test {
                      static void f(Object a, boolean b) {}
                      static void f(Object a, Object b) {}
                  
                      static void m(int a, boolean b) { f(a,b); }
                  }
                  

                  编译时出现如下错误:

                  Test.java:5: reference to f is ambiguous, both method
                      f(java.lang.Object,boolean) in Test and method
                      f(java.lang.Object,java.lang.Object) in Test match
                  
                  static void m(int a, boolean b) { f(a, b); }
                                                    ^
                  

                  这个错误的修复很简单:只需使用显式自动装箱:

                  The fix to this error is trivial: just use explicit auto-boxing:

                  static void m(int a, boolean b) { f((Object)a, b); }
                  

                  按预期正确调用第一个重载.

                  Which correctly calls the first overload as expected.

                  那么为什么重载解析失败了?为什么编译器不自动装箱第一个参数,并正常接受第二个参数?为什么我必须明确请求自动装箱?

                  So why did the overload resolution fail? Why didn't the compiler auto-box the first argument, and accept the second argument normally? Why did I have to request auto-boxing explicitly?

                  推荐答案

                  当你自己将第一个参数强制转换为 Object 时,编译器将匹配方法而不使用自动装箱(JLS3 15.12.2):

                  When you cast the first argument to Object yourself, the compiler will match the method without using autoboxing (JLS3 15.12.2):

                  第一阶段(§15.12.2.2)执行未经允许的重载决议装箱或拆箱转换,或使用可变参数方法调用.如果没有适用的方法在这个阶段发现然后处理继续到第二个阶段.

                  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.

                  如果你不显式地强制转换,它会进入第二阶段,试图找到匹配的方法,允许自动装箱,然后确实是模棱两可,因为你的第二个参数可以通过布尔值或对象匹配.

                  If you don't cast it explicitly, it will go to the second phase of trying to find a matching method, allowing autoboxing, and then it is indeed ambiguous, because your second argument can be matched by boolean or Object.

                  第二阶段(§15.12.2.3)执行重载决议,同时允许装箱和拆箱,但仍然排除使用可变参数方法调用.

                  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.

                  为什么在第二阶段,编译器不选择第二种方法,因为不需要对布尔参数进行自动装箱?因为在找到这两种匹配方法后,仅使用子类型转换来确定这两种方法中最具体的方法,而不管最初为匹配它们而发生的任何装箱或拆箱(第 15.12.2.5 节).

                  Why, in the second phase, doesn't the compiler choose the second method because no autoboxing of the boolean argument is necessary? Because after it has found the two matching methods, only subtype conversion is used to determine the most specific method of the two, regardless of any boxing or unboxing that took place to match them in the first place (§15.12.2.5).

                  另外:编译器不能总是根据需要的自动(取消)装箱次数选择最具体的方法.它仍然可能导致模棱两可的情况.例如,这仍然是模棱两可的:

                  Also: the compiler can't always choose the most specific method based on the number of auto(un)boxing needed. It can still result in ambiguous cases. For example, this is still ambiguous:

                  public class Test {
                      static void f(Object a, boolean b) {}
                      static void f(int a, Object b) {}
                  
                      static void m(int a, boolean b) { f(a, b); } // ambiguous
                  }
                  

                  请记住,用于选择匹配方法的算法(编译时步骤 2)是固定的,并在 JLS 中进行了描述.一旦进入第 2 阶段,就没有选择性的自动装箱或拆箱.编译器将定位 所有 可访问的方法(这两种情况下的两种方法)和适用的方法(同样是两种方法),然后才选择最具体的方法而不查看装箱/拆箱,即这里有歧义.

                  Remember that the algorithm for choosing a matching method (compile-time step 2) is fixed and described in the JLS. Once in phase 2 there is no selective autoboxing or unboxing. The compiler will locate all the methods that are accessible (both methods in these cases) and applicable (again the two methods), and only then chooses the most specific one without looking at boxing/unboxing, which is ambiguous here.

                  这篇关于为什么自动装箱会使 Java 中的某些调用模棱两可?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Compiling C++ for the JVM(为 JVM 编译 C++)
                  Compile to java bytecode (without using Java)(编译成java字节码(不使用Java))
                  How to drive C#, C++ or Java compiler to compute 1+2+3+...+1000 at compile time?(如何在编译时驱动 C#、C++ 或 Java 编译器计算 1+2+3+...+1000?)
                  Java ClassLoader: load same class twice(Java ClassLoader:两次加载相同的类)
                  How to debug .class files in ECLIPSE?(如何在 ECLIPSE 中调试 .class 文件?)
                  Java quot;The blank final field may not have been initializedquot; Anonymous Interface vs Lambda Expression(Java“可能尚未初始化空白的最终字段匿名接口与 Lambda 表达式)

                  • <bdo id='zyA0R'></bdo><ul id='zyA0R'></ul>

                      1. <legend id='zyA0R'><style id='zyA0R'><dir id='zyA0R'><q id='zyA0R'></q></dir></style></legend>
                      2. <i id='zyA0R'><tr id='zyA0R'><dt id='zyA0R'><q id='zyA0R'><span id='zyA0R'><b id='zyA0R'><form id='zyA0R'><ins id='zyA0R'></ins><ul id='zyA0R'></ul><sub id='zyA0R'></sub></form><legend id='zyA0R'></legend><bdo id='zyA0R'><pre id='zyA0R'><center id='zyA0R'></center></pre></bdo></b><th id='zyA0R'></th></span></q></dt></tr></i><div id='zyA0R'><tfoot id='zyA0R'></tfoot><dl id='zyA0R'><fieldset id='zyA0R'></fieldset></dl></div>
                          <tbody id='zyA0R'></tbody>

                        1. <small id='zyA0R'></small><noframes id='zyA0R'>

                          • <tfoot id='zyA0R'></tfoot>