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.

Bài Viết Liên Quan

Chủ đề