The number of try blocks is always the same with the number of catch blocks

When executing Java code, different errors can occur: coding errors made by the programmer, errors due to wrong input, or other unforeseeable things.

When an error occurs, Java will normally stop and generate an error message. The technical term for this is: Java will throw an exception (throw an error).


Java try and catch

The try statement allows you to define a block of code to be tested for errors while it is being executed.

The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.

The try and catch keywords come in pairs:

Syntax

try {
  //  Block of code to try
}
catch(Exception e) {
  //  Block of code to handle errors
}

Consider the following example:

This will generate an error, because myNumbers[10] does not exist.

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}

The output will be something like this:

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
1

Try it Yourself »

If an error occurs, we can use

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
2 to catch the error and execute some code to handle it:

Example

public class Main {
  public static void main(String[ ] args) {
    try {
      int[] myNumbers = {1, 2, 3};
      System.out.println(myNumbers[10]);
    } catch (Exception e) {
      System.out.println("Something went wrong.");
    }
  }
}

The output will be:

Try it Yourself »


Finally

The

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
3 statement lets you execute code, after
public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
2, regardless of the result:

Example

public class Main {
  public static void main(String[] args) {
    try {
      int[] myNumbers = {1, 2, 3};
      System.out.println(myNumbers[10]);
    } catch (Exception e) {
      System.out.println("Something went wrong.");
    } finally {
      System.out.println("The 'try catch' is finished.");
    }
  }
}

The output will be:

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
5

Try it Yourself »



The throw keyword

The

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
6 statement allows you to create a custom error.

The

public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
6 statement is used together with an exception type. There are many exception types available in Java:
public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
8,
public class Main {
  public static void main(String[ ] args) {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // error!
  }
}
9,
public class Main {
  public static void main(String[ ] args) {
    try {
      int[] myNumbers = {1, 2, 3};
      System.out.println(myNumbers[10]);
    } catch (Exception e) {
      System.out.println("Something went wrong.");
    }
  }
}
0,
public class Main {
  public static void main(String[ ] args) {
    try {
      int[] myNumbers = {1, 2, 3};
      System.out.println(myNumbers[10]);
    } catch (Exception e) {
      System.out.println("Something went wrong.");
    }
  }
}
1, etc:

Example

Throw an exception if age is below 18 (print "Access denied"). If age is 18 or older, print "Access granted":

The

try doSomething(); // SyntaxError
catch (e) console.log(e);
2 statement is comprised of a
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block and either a
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block, a
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block, or both. The code in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block is executed first, and if it throws an exception, the code in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block will be executed. The code in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block will always be executed before control flow exits the entire construct.

Try it

Syntax

try {
  tryStatements
} catch (exceptionVar) {
  catchStatements
} finally {
  finallyStatements
}

try doSomething(); // SyntaxError
catch (e) console.log(e);
9

The statements to be executed.

try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
0

Statement that is executed if an exception is thrown in the

try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block.

try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
2 Optional

An optional identifier to hold the caught exception for the associated

try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block. If the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block does not utilize the exception's value, you can omit the
try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
2 and its surrounding parentheses, as
try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
6.

try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
7

Statements that are executed before control flow exits the

try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
8 construct. These statements execute regardless of whether an exception was thrown or caught.

Description

The

try doSomething(); // SyntaxError
catch (e) console.log(e);
3 statement always starts with a
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block. Then, a
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block or a
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block must be present. It's also possible to have both
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 and
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 blocks. This gives us three forms for the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 statement:

  • try doSomething(); // SyntaxError
    catch (e) console.log(e);
    
    2
  • try {
      myroutine(); // may throw three types of exceptions
    } catch (e) {
      if (e instanceof TypeError) {
        // statements to handle TypeError exceptions
      } else if (e instanceof RangeError) {
        // statements to handle RangeError exceptions
      } else if (e instanceof EvalError) {
        // statements to handle EvalError exceptions
      } else {
        // statements to handle any unspecified exceptions
        logMyErrors(e); // pass exception object to error handler
      }
    }
    
    7
  • try {
      throw "myException"; // generates an exception
    } catch (e) {
      // statements to handle any exceptions
      logMyErrors(e); // pass exception object to error handler
    }
    
    8

Unlike other constructs such as

try {
  myroutine(); // may throw three types of exceptions
} catch (e) {
  if (e instanceof TypeError) {
    // statements to handle TypeError exceptions
  } else if (e instanceof RangeError) {
    // statements to handle RangeError exceptions
  } else if (e instanceof EvalError) {
    // statements to handle EvalError exceptions
  } else {
    // statements to handle any unspecified exceptions
    logMyErrors(e); // pass exception object to error handler
  }
}
9 or
try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // statements to handle this very common expected error
  } else {
    throw e; // re-throw the error unchanged
  }
}
0, the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3,
try doSomething(); // SyntaxError
catch (e) console.log(e);
4, and
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 blocks must be blocks, instead of single statements.

try doSomething(); // SyntaxError
catch (e) console.log(e);

A

try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block contains statements that specify what to do if an exception is thrown in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block. If any statement within the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block (or in a function called from within the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block) throws an exception, control is immediately shifted to the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block. If no exception is thrown in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block, the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block is skipped.

The

try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block will always execute before control flow exits the
try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
8 construct. It always executes, regardless of whether an exception was thrown or caught.

You can nest one or more

try doSomething(); // SyntaxError
catch (e) console.log(e);
3 statements. If an inner
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 statement does not have a
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block, the enclosing
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 statement's
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block is used instead.

You can also use the

try doSomething(); // SyntaxError
catch (e) console.log(e);
3 statement to handle JavaScript exceptions. See the JavaScript Guide for more information on JavaScript exceptions.

Unconditional catch-block

When a

try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block is used, the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block is executed when any exception is thrown from within the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block. For example, when the exception occurs in the following code, control transfers to the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block.

try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}

The

try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block specifies an identifier (
openMyFile();
try {
  // tie up a resource
  writeMyFile(theData);
} finally {
  closeMyFile(); // always close the resource
}
4 in the example above) that holds the value of the exception; this value is only available in the scope of the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block.

Conditional catch-blocks

You can create "Conditional

try doSomething(); // SyntaxError
catch (e) console.log(e);
4-blocks" by combining
try doSomething(); // SyntaxError
catch (e) console.log(e);
2 blocks with
openMyFile();
try {
  // tie up a resource
  writeMyFile(theData);
} finally {
  closeMyFile(); // always close the resource
}
8 structures, like this:

try {
  myroutine(); // may throw three types of exceptions
} catch (e) {
  if (e instanceof TypeError) {
    // statements to handle TypeError exceptions
  } else if (e instanceof RangeError) {
    // statements to handle RangeError exceptions
  } else if (e instanceof EvalError) {
    // statements to handle EvalError exceptions
  } else {
    // statements to handle any unspecified exceptions
    logMyErrors(e); // pass exception object to error handler
  }
}

A common use case for this is to only catch (and silence) a small subset of expected errors, and then re-throw the error in other cases:

try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // statements to handle this very common expected error
  } else {
    throw e; // re-throw the error unchanged
  }
}

The exception identifier

When an exception is thrown in the

try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block,
function doIt() {
  try {
    return 1;
  } finally {
    return 2;
  }
}

doIt(); // returns 2
0 (i.e., the
openMyFile();
try {
  // tie up a resource
  writeMyFile(theData);
} finally {
  closeMyFile(); // always close the resource
}
4 in
function doIt() {
  try {
    return 1;
  } finally {
    return 2;
  }
}

doIt(); // returns 2
2) holds the exception value. You can use this identifier to get information about the exception that was thrown. This identifier is only available in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block's scope. If you don't need the exception value, it could be omitted.

function isValidJSON(text) {
  try {
    JSON.parse(text);
    return true;
  } catch {
    return false;
  }
}

The finally-block

The

try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block contains statements to execute after the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block and
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block(s) execute, but before the statements following the
try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
8 block. Control flow will always enter the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block, which can proceed in one of the following ways:

  • Immediately before the
    try doSomething(); // SyntaxError
    catch (e) console.log(e);
    
    3 block finishes execution normally (and no exceptions were thrown);
  • Immediately before the
    try doSomething(); // SyntaxError
    catch (e) console.log(e);
    
    4 block finishes execution normally;
  • Immediately before a control-flow statement (
    try {
      try {
        throw new Error("oops");
      } finally {
        console.log("finally");
      }
    } catch (ex) {
      console.error("outer", ex.message);
    }
    
    // Logs:
    // "finally"
    // "outer" "oops"
    
    1,
    try {
      try {
        throw new Error("oops");
      } finally {
        console.log("finally");
      }
    } catch (ex) {
      console.error("outer", ex.message);
    }
    
    // Logs:
    // "finally"
    // "outer" "oops"
    
    2,
    try {
      try {
        throw new Error("oops");
      } finally {
        console.log("finally");
      }
    } catch (ex) {
      console.error("outer", ex.message);
    }
    
    // Logs:
    // "finally"
    // "outer" "oops"
    
    3,
    try {
      try {
        throw new Error("oops");
      } finally {
        console.log("finally");
      }
    } catch (ex) {
      console.error("outer", ex.message);
    }
    
    // Logs:
    // "finally"
    // "outer" "oops"
    
    4) is executed in the
    try doSomething(); // SyntaxError
    catch (e) console.log(e);
    
    3 block or
    try doSomething(); // SyntaxError
    catch (e) console.log(e);
    
    4 block.

If an exception is thrown from the

try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block, even when there's no
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block to handle the exception, the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block still executes, in which case the exception is still thrown immediately after the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block finishes executing.

The following example shows one use case for the

try doSomething(); // SyntaxError
catch (e) console.log(e);
5-block. The code opens a file and then executes statements that use the file; the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5-block makes sure the file always closes after it is used even if an exception was thrown.

openMyFile();
try {
  // tie up a resource
  writeMyFile(theData);
} finally {
  closeMyFile(); // always close the resource
}

Control flow statements (

try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"
1,
try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"
2,
try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"
3,
try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"
4) in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block will "mask" any completion value of the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block or
try doSomething(); // SyntaxError
catch (e) console.log(e);
4 block. In this example, the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 block tries to return 1, but before returning, the control flow is yielded to the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block first, so the
try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block's return value is returned instead.

function doIt() {
  try {
    return 1;
  } finally {
    return 2;
  }
}

doIt(); // returns 2

It is generally a bad idea to have control flow statements in the

try doSomething(); // SyntaxError
catch (e) console.log(e);
5 block. Only use it for cleanup code.

Examples

Nested try-blocks

First, let's see what happens with this:

try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"

Now, if we already caught the exception in the inner

try doSomething(); // SyntaxError
catch (e) console.log(e);
3-block by adding a
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block:

try {
  try {
    throw new Error("oops");
  } catch (ex) {
    console.error("inner", ex.message);
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "inner" "oops"
// "finally"

And now, let's rethrow the error.

try doSomething(); // SyntaxError
catch (e) console.log(e);
0

Any given exception will be caught only once by the nearest enclosing

try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block unless it is rethrown. Of course, any new exceptions raised in the "inner" block (because the code in
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block may do something that throws), will be caught by the "outer" block.

Returning from a finally-block

If the

try doSomething(); // SyntaxError
catch (e) console.log(e);
5-block returns a value, this value becomes the return value of the entire
try doSomething(); // SyntaxError
catch (e) console.log(e);
09 statement, regardless of any
try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"
1 statements in the
try doSomething(); // SyntaxError
catch (e) console.log(e);
3 and
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-blocks. This includes exceptions thrown inside of the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block:

try doSomething(); // SyntaxError
catch (e) console.log(e);
1

The outer "oops" is not thrown because of the return in the

try doSomething(); // SyntaxError
catch (e) console.log(e);
5-block. The same would apply to any value returned from the
try doSomething(); // SyntaxError
catch (e) console.log(e);
4-block.

Is the number of try blocks is always the same with the number of catch blocks?

As I mentioned above, a single try block can have any number of catch blocks.

How many catch blocks can be there for a try block?

Explanation: There is no limit on the number of catch blocks corresponding to a try block. This is because the error can be of any type and for each type, a new catch block can be defined. This is to make sure all type of exceptions can be handled. 10.

Can there be a catch block without a matching try block?

Yes, It is possible to have a try block without a catch block by using a final block. As we know, a final block will always execute even there is an exception occurred in a try block, except System.

Can you have more than one catch block associated with the same try block?

Yes you can have multiple catch blocks with try statement. You start with catching specific exceptions and then in the last block you may catch base Exception . Only one of the catch block will handle your exception. You can have try block without a catch block.