java中的构造函数

时间:2011-09-03 13:22:17

标签: java constructor

public class A {
public A() {
    System.out.println("a1");
}
public A(int x) {
    System.out.println("a2");

}}

public class B extends A {
public B() {
    super(5);
    System.out.println("b1");
}
public B(int x) {
    this();
    System.out.println("b2");
}
public B(int x, int y) {
    super(x);
    System.out.println("b3");
}}

我不明白为什么在运行B b= new B();

时不会应用A的默认结构

B扩展A,所以首先我们称A的结构应该打印“a1”,然后我们称A的第二个结构打印“a2”并且B()打印“b1”,但是当我运行它时,它只打印“a2,b1”,所以显然A()在开始时没有应用 - 为什么?

4 个答案:

答案 0 :(得分:4)

当您说B b = new B();时,您正在调用默认构造函数

public B() {
    super(5);
    System.out.println("b1");
}

由于这已经调用了它的超级构造函数[super(5)],因此编译器不会插入隐式默认构造函数。因此结果。

注意:根据您的问题,您似乎认为在创建对象时会调用所有构造函数。我担心这是不正确的。只会调用那个构造函数,您将显式调用该构造函数来创建对象。如果该构造函数通过this()方法调用其他构造函数,则只会调用其他构造函数。

答案 1 :(得分:2)

那是因为你在B构造函数中调用super(5)来调用第二个构造函数而不是第一个构造函数。

答案 2 :(得分:2)

  

B延伸A,所以首先我们称A的结构应该打印“a1”

此声明不正确。 在B类中你没有参数构造函数

public B() {
    super(5);
    System.out.println("b1");
}

调用超类(A类)的构造函数,该构造函数接受一个int参数。

public A(int x) {
    System.out.println("a2");
}

您永远不会调用 super(),因此当您调用任何B的构造函数时,不会调用打印“a1”的构造函数

调用超级构造函数必须是构造函数的第一行。如果你想调用超类的无参数构造函数(在这种情况下,打印“a1”的那个),你会写...

public B() {
    super();
    System.out.println("b1");
}

如果你没有指定调用超级构造函数,那么java会自动调用no参数的超级构造函数。

答案 3 :(得分:2)

我认为您错过了解Java如何处理构造函数。首先,默认情况下,Java将为每个类调用仅一个构造函数,除非您明确告诉它使用this(...)调用更多。其次,被调用的一个构造是超类的默认构造函数(因此它将调用super(),而不是this());所以班级A实际上是这样的:

public class A {
  public A() {
     super(); // implicit call to super(), which is Object()
     System.out.println("a1");
  }
  public A(int x) {
    super(); // implicit call to super(), which is Object()
    System.out.println("a2");
  }
}

所以调用A()会隐式调用Object(),但是调用A(int x) 也会隐式调用Object(),而不是 - 你好像怎么样假设 - A()

因为在B中你总是明确指定调用另一个构造函数,所以编译器不会添加任何东西。下面我添加了关于对super(...)this(...)

的调用会发生什么的评论
   public class B extends A {
      public B() {
        super(5); // explicit call to A(5), no implict call to A()
        System.out.println("b1");
      }
      public B(int x) {
        this(); // explicit call to B(), no implicit call to A()
        System.out.println("b2");
      }
      public B(int x, int y) {
        super(x); // explict call to A(x), no implicit call to A()
        System.out.println("b3");
      }
    }

重要的是,要记住的重要一点是Java将在任何构造函数的第一行中插入对super()的调用,除非您使用this(...)super(...)显式调用另一个构造函数。 永远不会自行插入this()