How do I call an empty constructor from another?

I have a code like this:

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();
}

      

I would like to know if something like this can be achieved (I know that calling another constructor must be the first expression in the constructor). I looked around here on SO but didn't find anything that made me believe that maybe I should handle the error logic in the instantiation method.

+3


source to share


4 answers


Just change the order of execution:



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 
    }
}

      

+3




In general, it is not a good practice to call code that might have inserted a constructor , and worse than throwing an exception from the caller altogether. However, what you can do is refactor your code so that you move the initialization of the parameterless constructor into the standard construct into a helper method, which you can then call from the exception handler in the second 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


source


As you said

another constructor call must be the first statement in Constructor

There are two solutions that I usually use when I need this behavior:

  • Make init function and call it from both places:

    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();
    }
    
          

  • Make a static function to initialize the object and return it.

    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();
    }
    
          

+2


source


Just don't do anything in the catch block in the constructor. It should work the way you want it to. However, take a look at try-catch-in-constructor-recommended-practice to get the right approach to your problem.

Also, if you are doing default initialization follow the approach outlined by @StuartLC

+1


source







All Articles