Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Throwing an exception through a constructor

Tags:

java

exception

Suppose I have the following piece of code:

public class Conf{    
  public Conf(String szPath) throws IOException, ConfErrorException{
      ...
  }
  public void someMethod(){
    ...
  }
}

Then I want to instantiate the object this way:

Conf configuration = new Conf("/etc/myapp/myconf.conf");

If, for some reason, the constructor throws any of the exceptions defined, will the object be created?
I mean, will I still be able to access the methods in it, for example, like in the following code?

Conf configuration;
try{
   configuration = new Conf("/etc/myapp/myconf.conf");
}catch(IOException|ConfErrorException e){
   //Suppose we entered here
   configuration.someMethod();
}
like image 612
Ander Juaristi Avatar asked May 16 '26 01:05

Ander Juaristi


2 Answers

Let me start with an scenario of failing object construction that can exemplify what could go wrong if you could use such failed object:

Let's define a class A, such that:

class A {
   private String a = "A";

   public A() throws Exception {
        throw new Exception();
   }
}

Now, let's assume we would like to create an object of type A in a try...catch block.

A a = null;
try{
  a = new A();
}catch(Exception e) {
  //...
}
System.out.println(a);

Evidently, the output of this code will be: null.

Why Java does not return a partially constructed version of A? After all, by the point the constructor fails its name field member has already being initialized, right?

Java does not do that because the object was not successfully built. The object is in a inconsistent state, and it is therefore discarded by Java. Your variable A is not even initialized, it is kept as null.

Now, as you know, to fully build a new object, all its super classes must be initialized first. If one of the super classes failed to build, what would be the final state of the object? It is impossible to determine that.

Look at this more elaborate example

class A {
   private final int a;
   public A() throws Exception { 
      a = 10;
   }
}

class B extends A {
   private final int b;
   public B() throws Exception {
       methodThatThrowsException(); 
       b = 20;
   }
}

class C extends B {
   public C() throws Exception { super(); }
}

When the constructor of C is invoked, if an exception occurs on initializing B, what would be the value of the final variable int b?

As such, the object C cannot be created, it is bogus, it is trash, it is not fully initialized.

like image 89
Edwin Dalorzo Avatar answered May 18 '26 14:05

Edwin Dalorzo


the constructor throws any of the exceptions defined, will the object be created?

The object is always created before the constructor is called. Otherwise there would be no this object in the constructor to initialise.

If you throw an Exception, you will lose a reference to that object, unless you have done something suspect like store the object in the constructor before throwing an exception.

public class Main {
    static class ThrowsException {
        static final List<ThrowsException> BAD_LIST = new ArrayList<>();

        ThrowsException() {
            System.out.println("this = " + this);
            BAD_LIST.add(this);
            throw new RuntimeException();
        }
    }

    public static void main(String... args) {
        for (int i = 0; i < 3; i++) {
            ThrowsException te = null;
            try {
                te = new ThrowsException();
            } catch (Exception ignored) {
            }
            System.out.println("te = " + te);
        }
        System.out.println(ThrowsException.BAD_LIST);
    }

prints

this = Main$ThrowsException@22911fb5
te = null
this = Main$ThrowsException@65b8b5cd
te = null
this = Main$ThrowsException@41a7d9e7
te = null
[Main$ThrowsException@22911fb5, Main$ThrowsException@65b8b5cd, Main$ThrowsException@41a7d9e7]
like image 35
Peter Lawrey Avatar answered May 18 '26 14:05

Peter Lawrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!