【问题标题】:Weird behaviour when overloading varargs method重载可变参数方法时的奇怪行为
【发布时间】:2018-12-13 13:54:03
【问题描述】:

通常,具有固定数量参数的方法优于具有可变数量参数的重载方法。但是,此示例的行为有所不同:

public class Main{
 public static void main(String[] args){
  print(1);
  print(1,2);
  print(new String[]{"a","b"});
  print(new String[][]{{"a","b"},{"c","d"}});
 }

 public static void print(Object object){
  System.out.println("single argument method");
  System.out.println(object);
 }

 public static void print(Object object0,Object object1){
  System.out.println("two argument method");
  System.out.println(object0);
  System.out.println(object1);
 }

 public static void print(Object... objects){
  System.out.println("varargs method with "+objects.length+" arguments");
  for(Object object : objects){
   System.out.println(object);
  }
 }
}

输出:

single argument method
1
two argument method
1
2
varargs method with 2 arguments
a
b
varargs method with 2 arguments
[Ljava.lang.String;@5e2de80c
[Ljava.lang.String;@1d44bcfa

main 的第三行用一个参数调用方法,它是一个带有两个元素的 String[]。但这不会执行带有一个参数的方法,而是执行 varargs 方法并表现得就像我给了它两个参数(这很正常,因为它是一个数组)。

现在的问题是:这应该发生吗?我是否发现了错误或未记录的行为?这样做有什么原因吗?

我为什么这样做:我想创建一个打印到控制台的快捷方式,它既可以接受任意数量的参数(用于多行),也可以以一种很好的方式打印数组和列表。

【问题讨论】:

    标签: java arrays variadic-functions overloading


    【解决方案1】:

    这应该发生吗?

    是的

    我是否发现了错误或未记录的行为?

    没有

    这样做有什么原因吗?

    是的。 From Oracle:

    在一个数组中必须传递多个参数仍然是正确的, 但可变参数功能会自动执行并隐藏该过程。此外, 它与预先存在的 API向上兼容

    当您显式使用数组时,它仍然匹配可变参数签名。这样做是为了让人们可以轻松地将数组参数切换为可变参数,而不会破坏现有的集成点。

    main 可以是String[]String... 的原因完全相同

    【讨论】:

    • 但它也将方法的签名与一个参数匹配。那为什么不叫那个呢?
    • 因为可变参数更具体,并且最具体的方法始终是选择的方法。鉴于您的用例,除了可变参数之外,您实际上并不需要单参数方法。
    • 不,如您所见,它选择print(1) 的单参数方法和print(1,2) 的双参数方法而不是varargs 方法。仅从逻辑上讲,它们更具体:它们指定了参数的数量,并且适用于较少的情况。
    猜你喜欢
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 2013-01-25
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多