【问题标题】:Constructor Chaining and Visibility in JavaJava中的构造函数链和可见性
【发布时间】:2018-09-01 04:41:08
【问题描述】:

考虑这个类:

public class Passenger {
  public Passenger() {

  }

  public Passenger(int freeBags) {
      this(freeBags > 1 ? 25.0d : 50.0d);
      this.freeBags = freeBags;
  }

  public Passenger(int freeBags, int checkedBags) {
      this(freeBags);
      this.checkedBags = checkedBags;
  }

  private Passenger(double perBagFee) {
      this.perBagFee = this.perBagFee;
  }
}


Passenger fred = new Passenger(2);

如果我理解正确,“fred”是Passenger 的一个新实例。 'fred' 用一个参数public Passgener(int freeBags) 调用构造函数。然后这条线this(freeBags > 1 ? 25.0d : 50.0d) 被调用。 这是我的问题:编译器如何知道第一个构造函数中的条件语句链接到“私有”构造函数?我的猜测是条件语句中的“d”指向私有构造函数中的双参数。但是如果有另一个带有双参数的构造函数呢?它会链接到什么?在第一个构造函数中没有提到perBagFee。我有点困惑。

【问题讨论】:

  • 但是如果有另一个带有双参数的构造函数呢? 试试看。为了节省你一分钟,那将是一个编译时错误(除非它有不同的签名)。

标签: java parameters constructor visibility chaining


【解决方案1】:

编辑

编译器如何知道第一个构造函数中的条件语句链接到“私有”构造函数?

由于您的三元表达式返回的任一值都是双精度值,因此编译器知道此调用引用了您的构造函数方法,该方法接收了一个双精度参数。

我的猜测是条件语句中的'd'指向私有构造函数中的双参数。

.0d 后缀仅表示它们是双精度值。

第一个构造函数中没有提到 perBagFee

方法参数名称与方法本身无关。编译器将始终检查您的表达式评估为哪种对象,以确定您要调用的方法。

但是如果有另一个带有双参数的构造函数呢?

试试看 :) 在同一个类中,无论可见性如何,都不能定义具有相同签名的两个方法(构造函数或非构造函数)。 Official docs on methods overloading:

重载的方法由传递给方法的参数的数量和类型来区分。

您不能声明具有相同名称、相同数量和类型的参数的多个方法,因为编译器无法区分它们。

【讨论】:

  • 谢谢,但这不是我要问的。让我澄清一下,当没有提到perBagFee时,这个三元表达式如何链接到私有构造函数?
  • @ginop86 哦,我现在明白了。重写了我的答案。
【解决方案2】:

你所看到的叫做重载

重载是一个用于避免冗余代码的概念 方法名称被多次使用,但使用了不同的集合 参数。在运行时调用的实际方法是 在编译时解析,从而避免运行时错误。

Java 不记得方法的变量名来识别要调用哪个重载构造函数,而是尝试匹配变量类型

Passenger(int) -> Passenger(10)

Passenger(int, int) -> Passenger(10,10)

Passenger(double) -> Passenger(2.5d)

所以,如果您定义了与Passenger(double) 相同模式的另一个构造函数 . Java会抛出编译时错误

构造函数Passenger(double)已经在Passenger类中定义

【讨论】:

    猜你喜欢
    • 2016-02-21
    • 1970-01-01
    • 2016-02-11
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多