Java:重载方法解析和可变参数——令人困惑的例子

发布于 2024-11-07 18:53:59 字数 1577 浏览 11 评论 0原文

正当我以为我理解了 JLS15.12 当它应用于可变参数时,这是这个例子:

package com.example.test.reflect;

public class MethodResolutionTest2 {
    public int compute(Object obj1, Object obj2) {
        return 42;
    }   
    public int compute(String s, Object... objects)
    {
        return 43;
    }

    public static void main(String[] args) {
        MethodResolutionTest2 mrt2 = new MethodResolutionTest2();
        System.out.println(mrt2.compute("hi",  mrt2));  
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2}));    
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2, mrt2, mrt2}));
    }
}

它打印出

42
43
43

我理解第一行:JLS15.12 表示方法解析分阶段发生,第 1 阶段和第 2 阶段忽略 varargs 方法来查找是否存在兼容的方法,只有在第 1 阶段和第 2 阶段失败时才会发生第 3 阶段(包括 varargs)。 (请参阅 JLS 和这个问题。< /a>) 因此,如果 compute(Object obj1, Object obj2) 应用,compute(String s, Object...objects) 总是会被忽略。

但我不明白为什么另外两行打印 43 。 Object[] 也是一个 Object 的实例,那么为什么它会匹配 varargs 方法呢?


编辑:

...这

Object arg2 = new Object[]{mrt2};
System.out.println(mrt2.compute("hi", arg2));   

会打印 42

Just when I thought I understood JLS15.12 as it applied to varargs, here's this example:

package com.example.test.reflect;

public class MethodResolutionTest2 {
    public int compute(Object obj1, Object obj2) {
        return 42;
    }   
    public int compute(String s, Object... objects)
    {
        return 43;
    }

    public static void main(String[] args) {
        MethodResolutionTest2 mrt2 = new MethodResolutionTest2();
        System.out.println(mrt2.compute("hi",  mrt2));  
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2}));    
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2, mrt2, mrt2}));
    }
}

which prints out

42
43
43

I understand the first line: JLS15.12 says method resolution happens in phases, and phases 1 and 2 ignore varargs methods to find out if there's a compatible method, with phase 3 (include varargs) happening only if phases 1 and 2 fail. (See the JLS and this SO question.) So compute(String s, Object... objects) always gets ignored if compute(Object obj1, Object obj2) applies.

But I don't understand why 43 is printed for the other two lines. An Object[] is also an instance of an Object, so why does it match the varargs method?


edit:

...and this

Object arg2 = new Object[]{mrt2};
System.out.println(mrt2.compute("hi", arg2));   

prints 42.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

有深☉意 2024-11-14 18:53:59

8.4.1 部分中:

如果最后一个形参是T类型的可变参数,
它被认为定义了类型 T[] 的形式参数。

由于您显式提供了一个数组,因此这允许后两个调用匹配第一阶段中的变量数量方法,而不考虑变量数量。

In section 8.4.1:

If the last formal parameter is a variable arity parameter of type T,
it is considered to define a formal parameter of type T[].

Since you're explicitly providing an array, this allows the second two calls to match the variable arity method in the first phase, without consideration of variable arity.

最偏执的依靠 2024-11-14 18:53:59

Vararg 方法可以使用多个参数 (a, b, c) 或作为数组 ({a, b, c}) 来调用。因为您传递的数组与可变参数的类型匹配,所以它优先。

参考: http://java.sun.com /docs/books/jls/third_edition/html/classes.html#8.4.1

Vararg methods can be called with multiple parameters (a, b, c) or as an array ({a, b, c}). Because you are passing an array that matches the type of the varargs it takes precedence.

Reference: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文