【问题标题】:Why is varargs always the last parameter in a method signature?为什么可变参数总是方法签名中的最后一个参数?
【发布时间】:2012-03-11 11:44:39
【问题描述】:

为什么varargs必须是方法签名中的最后一个参数?

我想知道原因。

【问题讨论】:

  • 如果不是这样,那么在方法使用中,编译器如何找出varargs结束和下一个方法arg开始的地方?
  • 可以通过首先识别非可变参数并将其余的作为可变参数来区分可变参数,无论它们出现在开头还是结尾。目前,如果有五个参数,最后一个是可变参数,那么它会被解析为第四个之后的参数是可变参数。这也可以反过来,就像如果有五个参数,第一个作为可变参数,从头到尾解析,就像最后四个是正常的,除了最后四个之外的任何东西都是第一个可变参数的一部分 :) 我认为它刚刚实现这样,因为到目前为止还没有真正的需要
  • 在此处查看对C family of language 创作者的采访 [C 家庭采访](gotw.ca/publications/c_family_interview.htm) 其中 Gosling 说:“我有一条个人规则,我没有放任何东西只是因为我觉得这很酷。因为我一直都有一个用户社区,所以我会等到几个人联合起来攻击我,然后再插入任何东西。如果有人说,“哦,那不是很酷”并且我忽略了他们,直到两三个人走过来对我说“Java 应该这样做。”然后我就开始了,好吧,也许人们会真正使用它。”

标签: java parameters variadic-functions method-signature


【解决方案1】:

因为它使编译器的工作更简单。没有真正的理由为什么它不能之后有更多的参数,但它需要一个更复杂的编译器,所以规范就是这样编写的。

【讨论】:

  • 感谢您的回答,但是通过上面的 cmets 我认为这是不可能的,对于示例:'public void test(String...names,String code)',编译器无法区分名称和代码参数。
  • 可以。它计算所有参数,将最后一个放在code 中,将所有其他参数放在names 中。
  • 您说得对,“varargs 必须始终放在最后”使 Java 编译器团队的工作更加轻松。但是,这并不是真正的解析问题,因为解析器会生成 AST。这条规则只是让编译器的许多其他部分(例如重载解析)变得更加容易。
  • @Adam Mihalcin 我不知道 AST 概念,请讨论更多及其与可变参数问题的关系。
  • @MJM AST 的定义超出了您的问题范围,但这里有一个注释大小的解释:编译器分为对源代码进行标记的词法分析器,构建抽象语法的解析器来自令牌的树(AST),一个可选的类型检查器和优化器,在 AST 上运行,以及一个代码生成器,用于将这些 AST 从某种内部表示形式转换为字节码。请参阅en.wikipedia.org/wiki/Compiler 了解编译器的工作原理。
【解决方案2】:

主要原因是因为它可能会模棱两可,否则......

例如,编译器如何判断参数是可变参数还是具有多个可变参数的长参数列表中的单独命名参数?

想象一下这样的方法签名:

printNames(String... girls, String... boys);

如果你做printNames("Lucy", "Jo", "Paul"),Jo 是男孩还是女孩?

作为另一个模棱两可的例子,在参数列表中较早地使用可变参数可能会在存在重载方法时导致问题。例如:

printFruit(String... apples, String orange);
printFruit(String... apples, String grapefruit, String orange);

编译器如何判断倒数第二个参数是葡萄柚还是苹果?

请注意,这不是 Java 独有的,大多数支持可变参数的语言出于相同的原因只允许 then 位于参数列表的末尾。

【讨论】:

  • “multiple varargs”与“varargs always last”完全是一个不同的问题。
  • @Ignacio Vazquez-Abrams 其他语言也不允许多个可变参数?
  • 它们密切相关....我认为可变参数的约束只是最后一个参数是导致多个可变参数是不可能的。
  • @mikera 我已经接受了你的评论(你说:“它们密切相关”)但是在最后一个示例中,编译器可以区分三个参数,最后两个参数是葡萄柚和橙子,其他的是苹果.
  • 编译器也有可能直接拒绝所有可能导致歧义的变体,而不是仅仅将其放入规范中。
猜你喜欢
  • 2011-01-10
  • 2011-09-15
  • 1970-01-01
  • 2012-08-07
  • 2017-05-14
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多