Java 中的构造函数链接和可见性

Constructor Chaining and Visibility in Java

考虑这个 class:

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) 被调用。 这是我的问题:编译器如何知道第一个构造函数中的条件语句链接到 'private' 构造函数?我的猜测是条件语句中的 'd' 指向私有构造函数中的双参数。但是如果有另一个带有双参数的构造函数呢?那它会链接到什么?第一个构造函数中没有提到 perBagFee 。我有点困惑。

编辑

How does the compiler know that the conditional statement in the first constructor to chain to the 'private' constructor?

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

My guess would be that the 'd' in the conditional statement points to the double parameter in the private constructor.

.0d 后缀仅表示这些是双精度值。

There is no mention of perBagFee in the first constructor

方法参数名称与方法本身无关。编译器将始终检查您的表达式求值的对象类型,以确定您要调用的方法。

But what if there was another constructor with a double parameter?

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

Overloaded methods are differentiated by the number and the type of the arguments passed into the method.

You cannot declare more than one method with the same name and the same number and type of arguments, because the compiler cannot tell them apart.

你能看到的叫做Overloading

Overloading is a concept used to avoid redundant code where the same method name is used multiple times but with a different set of parameters. The actual method that gets called during runtime is resolved at compile time, thus avoiding runtime errors.

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

Passenger(int) -> Passenger(10)

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

Passenger(double) -> Passenger(2.5d)

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

constructor Passenger(double) is already defined in class Passenger