简体   繁体   English

重载varargs数组,选择方法

[英]Overloading varargs arrays, choosing method

I have a two overloaded methods: foo and bar 我有两个重载方法: foobar

//Object[]... vs Integer[]...
public static String foo(Object[]... args)  { return "Object[] args"; }
public static String foo(Integer[]... args) { return "Integer[] args";}

//Object... vs Integer[]...
public static String bar(Object... args) {return "Object args";}
public static String bar(Integer[]... args) {return "Integer[] args";}

Now when I use them like: 现在当我使用它们时:

Integer[] i = { 5 };
System.out.println(foo(i));//Object[]... vs Integer[]...
System.out.println(bar(i));//Object... vs Integer[]...

I am getting 我正进入(状态

Integer[] args
Object args

Here is the question: why do we have 2 different outputs? 这是一个问题:为什么我们有两种不同的输出?
Integer[] can be implicitly cast to both Object , and Object[] . Integer[]可以隐式地转换为ObjectObject[]

In the first case, the type of args is actually Integer[][], ie, your array was boxed up into another array by varargs. 在第一种情况下,args的类型实际上是Integer [] [],即你的数组被varargs装入另一个数组。 The compiler chooses the Integer[] version because it is the most specific type. 编译器选择Integer []版本,因为它是最具体的类型。

In the second case, args == i and is an Integer[]. 在第二种情况下,args == i并且是一个Integer []。 In this case, the compiler had to choose between wrapping it up in a new array to call the Integer[]... version or just casting your Integer[] to an Object[]. 在这种情况下,编译器必须选择将它包装在一个新数组中以调用Integer [] ...版本,或者只是将Integer []转换为Object []。 It chose the second one because that's the rule. 它选择了第二个,因为这是规则。

The moral of the story is: don't overload varargs methods -- it's confusing. 故事的寓意是:不要超载varargs方法 - 这是令人困惑的。

This is basically compiler deciding to call the most specific method among all. 这基本上是编译器决定在所有方法中调用最具体的方法。

When you call 你打电话的时候

System.out.println(foo(i));//Object[]... vs Integer[]...

it will call the foo(Integer[]... args) 它将调用foo(Integer[]... args)

Because at run time the JVM delegates the call to the method with Integer[][] argument and not method with Object[][] param as specified by varags. 因为在运行时,JVM使用Integer[][]参数委托对方法的调用,而不是使用 varags指定的Object[][] param方法。 As it will be more specific to call method with Integer[][] rather than Object[][]. 因为使用Integer [] []而不是Object [] []调用方法会更具体。


In the later statement, when you call 在后面的陈述中,当你打电话

System.out.println(bar(i));//Object... vs Integer[]...

it will go to the bar(Object... args) 它会去吧bar(Object... args)

Again by using varags, the type of param will be Object[] and not Object[][]. 再次使用varags,param的类型将是Object []而不是Object [] []。 Again the compiler will call the most specific method which will be the one having Object... args . 编译器将再次调用最具体的方法,该方法将具有Object... args

If you change the method signature by removing varags as per following: 如果您通过删除varags更改方法签名,如下所示:

   //Object... vs Integer[]...
    public static String bar(Object args) {

        return "Object args";
    }

    public static String bar(Integer[] args) {
        return "Integer[] args";
    }

then you will notice that it will call the bar(Integer[] args) as it is more specific to the method call. 然后你会注意到它将调用bar(Integer[] args)因为它更具体的方法调用。

So to be more precise as per JLS Subtyping among Array Types , 因此,根据数组类型中的JLS子类型更精确,

  • If S and T are both reference types, then S[] > T[] iff S > T. 如果S和T都是引用类型,则S []> T [] iff S> T.
  • Object > Object[] 对象>对象[]

This means that a call of Integer[] will be made to method having Integer[][] and not Object[][]. 这意味着将对具有Integer [] []而不是Object [] []的方法调用Integer []。 Where as a call of Integer[] will be made to Object[] rather than Integer[][]. 其中Integer []的调用将发送到Object []而不是Integer [] []。

See here for choosing the most specific method. 请参阅此处以选择最具体的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM