Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this the correct exercise solution?

Tags:

java

exception

There is a exercise from Thinking in Java:

Create a class called FailingConstructor with a constructor that might fail partway through the construction process and throw an exception. In main(), write code that properly guards against this failure.

This is my solution:

class E1 extends Exception {
    private FailingConstructor f;
    E1(FailingConstructor f) { this.f = f; }
    FailingConstructor getF() { return f; }
}

class FailingConstructor {
    private Integer value;
    FailingConstructor(int i) throws E1 {
        if (i < 0) throw new E1(this);
        value = i;
    }
    void set(int value) { this.value = value; }
    public String toString() { return value.toString(); }
}

public class Program {
    public static void main(String[] args) {
        try {
            FailingConstructor f2 = new FailingConstructor(-11);
        } catch (E1 e) {
            e.getF().set(0);
            System.out.println(e.getF());
        }
    }
}

Could you please tell me, is this the correct exercise solution? Solution I found (here) looks rather strange and illogicaly and I think my solution is better than this.

like image 680
luckystrrrike Avatar asked Mar 08 '26 11:03

luckystrrrike


2 Answers

Passing a reference of the half constructed instance to the constructor of the exception seems like a bad idea to me.

And mutating that instance in the catch clause serves no purpose, since after the catch clause is executed, your code will have no reference to that instance anyway.

The catch clause should either report that an exception occurred (print an error message or stack trace), throw a different exception if applicable or - if properly guards against this failure means that the successful creation of an instance must be ensured - create a new instance of FailingConstructor whose creation is guaranteed not to throw an exception. If you choose the last approach, you should declare the FailingConstructor variable before the try block, in order for it to remain in scope after the try-catch block.

public class Program {
    public static void main(String[] args) {
        FailingConstructor f2 = null;
        try {
            f2 = new FailingConstructor(-11);
        } catch (E1 e) {
            f2 = new FailingConstructor(); // one way to recover from the exception 
                                           // is to use a different constructor
                                           // that doesn't throw an exception
        }
        // now you can access f2
    }
}
like image 117
Eran Avatar answered Mar 10 '26 23:03

Eran


Leaking the reference to the partly-constructed instance via the throw new E1(this) is ill-advised.

It lets you call e.getF().set(-1), and use the instance afterwards - which is exactly what the exception is being thrown to guard against.

There is no problem with throwing an exception - the problem is the reference to FailingConstructor that it is constructed with. Remove this (and the getF() method etc), and it is fine.

like image 23
Andy Turner Avatar answered Mar 11 '26 00:03

Andy Turner



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!