如何从另一个调用空构造函数?

时间:2017-06-25 11:23:18

标签: java constructor

我有一些像这样的代码:

public class Foo {
    private int x;

    public Foo() {
    }

    public Foo(int x) {
        try {
            //do some initialisation stuff like:
            this.x = x;
        }
        catch(Exception ge){
            //call empty constructor not possible
            //this();
            //this.EMPTY();
            //Foo();
        }
    }

    public static final Foo EMPTY = new Foo();
}

我想知道是否有可能实现这样的东西(我知道调用另一个构造函数必须是构造函数中的第一个语句)。 我在这里环顾四周,但是没有发现任何东西,让我相信也许,我应该在实例化方法中处理错误逻辑。

4 个答案:

答案 0 :(得分:3)

只需更改执行顺序:

public class Foo {

    Integer i;
    public Foo() {
        System.out.println("Empty constructor invoked");
    }

    public Foo(Integer i) {

        this(); //can be omitted

        try {
            System.out.println("i initialized to : "+i.toString());

        } catch (Exception ex) {

            System.out.println("i NOT initialized ");
        }
    }


    public static void main(String[] args) {

        new Foo(); //prints: Empty constructor invoked

        new Foo(5);//prints: Empty constructor invoked
                   //prints: i initialized to : 5

        new Foo(null);//prints: Empty constructor invoked
                   //prints: i NOT initialized 
    }
}

答案 1 :(得分:2)

一般情况下,调用可能throw in a constructor的代码并不是很好的做法,更糟糕的是完全抑制来自调用者的异常。但是,您可以做的是重构代码,以便将无参数构造函数的“默认”初始化移动到辅助方法中,然后可以从第二个构造函数中的异常处理程序调用该方法:

public class Foo {
    private int x;

    public Foo() {
      doDefaultInitialize();
    }

    public Foo(int x) {
        try {
          // dodgy code which could throw
        }
        catch(Exception ge){
          doDefaultInitialize();        
        }
    }

    private void doDefaultInitialize() {
       // Fallback initialization goes here
       x = 42;
    }
}        

答案 2 :(得分:2)

正如你所说

  

调用另一个构造函数必须是该中的第一个语句   构造

当我需要这种行为时,通常会使用2种解决方案:

  1. 创建一个init函数并从两个地方调用它:

    public class Foo {
        private int x;
    
        public Foo() {
            init();
        }
    
        public Foo(int x) {
            try {
                //do some initialisation stuff like:
                this.x = x;
            }
            catch(Exception ge){
                init();
            }
        }
    
        private init() {
            //Do the default initialization here...
        }
    
        public static final Foo EMPTY = new Foo();
    }
    
  2. 创建一个静态函数来初始化对象并将其返回。

    public class Foo {
        private int x;
    
        private Foo() {
            this.x = 42;
        }
    
        private Foo(int x) throws Exception {
            //do some initialization stuff like:
            this.x = x;
        }
    
        public static Foo getNewInstance(int x) {
            try {
                return new Foo(x);
            } catch (Exception e) {
                return new Foo();
            }
        }
    
        public static final Foo EMPTY = getNewInstance();
    }
    

答案 3 :(得分:1)

在构造函数的catch块中什么也不做。它应该按你的意愿工作。 但是,请查看此try-catch-in-constructor-recommended-practice以选择正确的问题解决方法。

此外,如果您正在进行任何默认初始化,请遵循@StuartLC

提及的方法