当前位置: 首页 > 知识库问答 >
问题:

重载varargs方法时的奇怪行为

晋言
2023-03-14

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

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的第三行用一个参数调用该方法,该参数是一个包含两个元素的字符串[]。但这并不是用一个参数执行方法,而是执行varargs方法,就像我给了它两个参数一样(这有点正常,因为它是一个数组)。

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

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

共有1个答案

方心思
2023-03-14

这应该发生吗?

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

它这样做有什么原因吗?

对来自Oracle:

的确,必须在一个数组中传递多个参数,但varargs功能会自动并隐藏该过程。此外,它与先前存在的API向上兼容。

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

这与main可以是String[]或String的原因完全相同

 类似资料:
  • 我有以下代码片段: 如果我调用foo(null)为什么没有歧义?为什么程序调用foo(字符串x)而不是foo(对象x)?

  • 我有两个重载的方法,分别是varargs int和long。当我运行一个传递整数的测试时,它似乎更喜欢varargs long方法。然而,如果我使这些方法是静态的并使用整数运行,它似乎更喜欢varargs int方法。这是怎么回事? 产出: 内长varargs 1 内部静态int varargs 1

  • 我正在尝试改变鼠标按钮,将地图视图从右键平移到左键。 在单击鼠标左键后,有一个简单的代码来更改按钮: 如何直接改变平移按钮,而不被释放和再次点击?谢谢你的帮助...

  • 问题内容: 考虑以下代码: 现在,更改方法的可见性,我得到: (for ,for ) (看起来像)。 我期望所有东西都像声明时一样。但是,尽管和本质上是同一件事,但根据in 和的可见性,它们会产生不同的结果。为什么会这样? 问题答案: 继承/覆盖私有方法 在PHP中,子类中的方法(包括私有方法)为: 复制;保留原始功能的范围。 已替换(如果需要,则为“覆盖”)。 您可以使用以下代码查看此内容: 现

  • 问题内容: 以下代码无法编译。 发出编译时错误。 对test的引用是模棱两可的,varargspkg.Main中的方法test(int …)和varargspkg.Main中的方法test(float …) 这似乎很明显,因为方法调用中的参数值可以提升为 如果任何一个或两个参数都带有或作为后缀,则会进行编译。 但是,如果我们用相应的包装器类型表示方法签名中的接收参数,如下所示 那么对该方法的调用不

  • 在Java 9中,在列表界面下,有一个新的()方法,根据Java文档: 名单。of()静态工厂方法提供了一种创建不可变列表的方便方法。