【问题标题】:How do I call this() and super(sth) in one java contructor?如何在一个 java 构造函数中调用 this() 和 super(sth)?
【发布时间】:2013-11-17 12:39:10
【问题描述】:

我想知道这种构造函数链调用在java中是否可行? 我正在扩展基本 JButton 类,我需要首先初始化超级变量,然后使用默认构造函数初始化我的类。

public CustomButton(){
    try {
        URL inp = CustomButton.class.getResource("/icons/noa_en/buttonBackground.png");
        background = ImageIO.read(inp);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public CustomButton(ImageIcon img){
    super(img);
    this();
}

或:

public CustomButton(ImageIcon img){
    this();
    super(img);
}

【问题讨论】:

  • 你试过吗?结果如何?
  • 是的,在这两种情况下,它都会给我“构造函数调用必须是构造函数中的第一条语句”。我正在使用 ecipe IDE。
  • 是的,但仍然给我同样的错误。如果你不相信我,请先尝试。
  • @armin this 或 super 应该是第一行,不能同时调用
  • 那会造成很大的问题,因为 this() 也会调用 super 方法。

标签: java constructor


【解决方案1】:

你只能调用另一个构造函数作为你在构造函数中的第一个动作。因此,当您想在类的两个构造函数中调用不同的超类构造函数时,您必须将公共代码重构为单独的方法:

public CustomButton() {
    // implicitly calls super() here
    setup();
}
public CustomButton(ImageIcon img) {
    super(img);
    setup();
}
private void setup() {
    // your init code
}

【讨论】:

  • 嗯,这可能是迄今为止最好的解决方案,但仍然必须在我的所有构造函数中重复 setup()。还有为什么在 java 中不能同时调用两个构造函数?它没有t 违反任何 OOP 规则。
  • 对于替代公式,以及关于 Java 中多个构造函数的一些建议,请查看 this question
【解决方案2】:

你不能这样称呼

public CustomButton(ImageIcon img){
    super(img);
    this();
}

因为super()this 将是第一行

所以你不能同时调用 super() 或 this()

【讨论】:

  • @gldraphael 您可以发布自己的答案
【解决方案3】:

您始终可以使用实例 initializing block 替换私有 init() 方法。
这样您就不需要在所有构造函数中重复调用init()。在 super() 构造函数完成后,将为每个构造函数调用此块。 请参阅下面的示例:

class Parent {
    Parent(String s) {
        System.out.println("parent constructor");
    }
}

class Child extends Parent {
    int x, y, z;
    {
        // do object initialization here
        // whatever you do in your setup() method you can do here
        // this block is executed before each constructor of Child class
        x = 1; y = 2; z = 3; // assign default values
        System.out.println("Child object initialization");
    }

    Child(int new_x) {
        super("parent");
        System.out.println("Child constructor");
        // do some specific initialization
        x = new_x;
    }

    public static void main(String... args) {
        Child c = new Child(3); // prints
        // parent constructor -> Child object initialization -> Child constructor
        System.out.println(c.x); // 3
    }
}

希望对您有所帮助。

【讨论】:

    【解决方案4】:

    在构造函数中,只能调用super()this() 构造函数。如果您不提供任何内容,则会隐式调用super()

    【讨论】:

    • 你说我们不能用参数调用 super(..) 或 this(..)?
    • 不,它给了我“构造函数调用必须是构造函数中的第一条语句”。不知道为什么。
    • 我的意思是,你只能调用另一个构造函数。它可以是超级构造函数,也可以是这个构造函数。论据没有问题。
    • @PrasadKharkar 谢谢,但我的问题是如何调用两者而不仅仅是一个。
    • @armin 据我所知,java 不允许你想要的。您可以做的是将登录名放入您希望在调用多个构造函数并调用该方法时执行的方法中。
    【解决方案5】:

    你只能从构造函数中调用一个构造函数,它应该是第一行。 您可以先调用this 构造函数,然后简单地从被调用的构造函数中调用super 构造函数。

    检查一下:

    class Parent {
    
        public Parent() {
            System.out.println("Parent: No args constructor called");
        }
    }
    
    public class Child extends Parent{
        String demo;
    
        public Child(String demo) {
            super();
            this.demo = demo;
            System.out.println("Child: Single arg constructor called");
        };
    
        public Child() {
            this("hello");
            System.out.println("Child: No arg constructor called");
        }
    
        public static void main(String args[]) {
            Child demo = new Child();
        }
    
    
    }
    

    输出:

    父级:没有调用 args 构造函数

    子:单参数构造函数

    被调用的孩子:没有调用 arg 构造函数

    【讨论】:

      【解决方案6】:

      this() & super() 只能在构造函数的第一行调用。
      这意味着您可以调用this()super(),因为只有其中一个可以占用第一行。

      如果您不提及this()super(),编译器将调用super()(不带参数)。

      我会通过以下方式解决您的问题:

      private void init()
      {
          try {
                  URL inp = CustomButton.class.getResource("/icons/noa_en/buttonBackground.png");
                  background = ImageIO.read(inp);
              } catch (IOException e) {
                  e.printStackTrace();
          }
      }
      
      public CustomButton()
      {
          init();
      }
      
      public CustomButton(ImageIcon img){
          super(img);
          init()
      }
      

      更新:

      注意您提供的代码:

      public CustomButton(){
          super();    // This gets automatically added to the constructor
          try {
              URL inp = CustomButton.class.getResource("/icons/noa_en/buttonBackground.png");
              background = ImageIO.read(inp);
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      

      注意CustomButton() 中的super()。所以在这种情况下,这意味着:

      public CustomButton(ImageIcon img){
          super(img);
          this();
      }
      

      super() 被调用了两次,一次被CustomButton() 调用,一次被CustomButton(ImageIcon img) 调用,这可能会导致意外结果,具体取决于JButton 的构造函数

      正是出于这个原因,Java 期望 this()super() 占据第一行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        • 2010-09-22
        相关资源
        最近更新 更多