Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it acceptable practice in Java to nest try/catch statements?

I am trying to create an IP address in Android from a passed in value (using Bundle), and if it fails I'm creating it using a default IP address that is hard coded. If that fails then I am exiting the app.

What I'd like to know is if its ok to nest try/catch's as I have done here, or is there a better way.

try {
    // serverSettings is the Bundle name that was passed in.
    ipAddress = InetAddress.getByName(serverSettings.getString("serverIp"));
} catch (UnknownHostException e) {
    Log.e("ERROR:", "IOException: Failed to create IP, trying default");
    try {
        // DEFAULT_IP is the hard-coded default fall-back address
        ipAddress = InetAddress.getByName(DEFAULT_IP);
    } catch (UnknownHostException e1) {
        Log.e("ERROR:", "IOException: Total fail, exiting");
        e1.printStackTrace();
        finish();
    }
}
like image 324
Steve Avatar asked Apr 25 '11 01:04

Steve


People also ask

Is it good practice to use nested try catch?

Although this is sometimes unavailable, nesting try/catch blocks severely impacts the readability of the source code as it makes it difficult to understand which block will catch which exception.

Can you nest try catch Java?

In Java, we can use a try block within a try block. Each time a try statement is entered, the context of that exception is pushed on to a stack. Given below is an example of a nested try.

When should I nest try catch?

When a try catch block is present in another try block then it is called the nested try catch block. Each time a try block does not have a catch handler for a particular exception, then the catch blocks of parent try block are inspected for that exception, if match is found that that catch block executes.

Is try with multiple catch allowed in Java explain?

Yes, we can define one try block with multiple catch blocks in Java. Every try should and must be associated with at least one catch block.


3 Answers

It's legal Java. It looks clunky to me, and I'd probably do it differently, but it's valid and works.

Here's how I'd do it:

public InetAddress getServerAddress() {
    for (String address : new String[] {serverSettings.getString("serverIp"), DEFAULT_IP}) {
        try {
            return InetAddress.getByName(address);
        } catch (UnknownHostException e) {
            Log.e("ERROR:", "Cannot resolve " + address);
        }
    }
    Log.e("ERROR:", "Total fail, exiting");
    finish();
    return null;    // not reached
}
like image 127
Chris Jester-Young Avatar answered Oct 01 '22 21:10

Chris Jester-Young


I think it's going to be debatable what way is better, but here's another option that some may consider to be a bit more "expressive" and readable, though it's more lines of code:

public InetAddress tryHost(String hostName) {
    InetAddress address = null;
    try {
        address = InetAddress.getByName(hostName);
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    return null;
}

Then in your code, just do:

InetAddress address = null;
address = tryHost(serverSettings.getString("serverIp"));
if (address = null)
    address = tryHost(DEFAULT_IP);
if (address = null) {
    // handle error, throw exception
}
finish();
like image 25
squawknull Avatar answered Oct 01 '22 22:10

squawknull


Another variation is to set the default first:

ipAddress = null;
try {
    // serverSettings is the Bundle name that was passed in.
    ipAddress = InetAddress.getByName(DEFAULT_IP); // Set default address
    ipAddress = InetAddress.getByName(serverSettings.getString("serverIp")); // Try passed-in address
} catch (UnknownHostException e) {
    if (ipAddress == null) {
        Log.e("ERROR:", "IOException: Total fail, exiting");
        e1.printStackTrace();
        finish();
    }
}

If the call using the Bundle'd value fails, then the exception is thrown before ipAddress is modified, so ipAddress is already set to the default. Of course, this is only a valid pattern if DEFAULT_IP should always be resolvable.

like image 45
Phil Lello Avatar answered Oct 01 '22 22:10

Phil Lello