850

In Java, I want to do something like this:

try {
    ...     
} catch (/* code to catch IllegalArgumentException, SecurityException, 
            IllegalAccessException, and NoSuchFieldException at the same time */) {
   someCode();
}

...instead of:

try {
    ...     
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

Is there any way to do this?

MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48
froadie
  • 79,995
  • 75
  • 166
  • 235

11 Answers11

1341

This has been possible since Java 7. The syntax for a multi-catch block is:

try { 
  ...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
            NoSuchFieldException e) { 
  someCode();
}

Remember, though, that if all the exceptions belong to the same class hierarchy, you can simply catch that base exception type.

Also note that you cannot catch both ExceptionA and ExceptionB in the same block if ExceptionB is inherited, either directly or indirectly, from ExceptionA. The compiler will complain:

Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA

The fix for this is to only include the ancestor exception in the exception list, as it will also catch exceptions of the descendant type.

M. Justin
  • 14,487
  • 7
  • 91
  • 130
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • 93
    T.T - why redefine the `bitwise or` (`|`) operator? Why not use a comma, or the operator that has a more similar meaning, the `logical or` (`||`)? – ArtOfWarfare Nov 06 '13 at 18:52
  • 14
    @ArtOfWarfare Maybe they thought it wouldn't matter anymore after they already had come up with the syntax for [multiple bounds](http://docs.oracle.com/javase/tutorial/java/generics/bounded.html) for generics. – JimmyB Mar 22 '16 at 11:08
  • 19
    XOR sign ( I ) is not the same as OR ( || ), A | B means either A or B *but* not both A || B means either A or B or both so as for exceptions it is either exceptionA or exceptionB but not both at the same time. this is why they used XOR sing instead of OR and you can see that clearly when the exception is throws if you put 2 exceptions one of them is sub type of another – user1512999 Mar 13 '17 at 06:06
  • 50
    @user1512999 in Java, bitwise XOR is ^ (caret) and bitwise OR is | (pipe) https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html – Lewis Baumstark Mar 28 '17 at 18:40
  • 10
    It's worth mentioning that the type of an exception caught in multi-catch block is evalueted to the most derived common parent – yanpas Feb 09 '18 at 11:16
  • 2
    @yanpas not exactly. E.g. when you re-throw the exception, it will be handled as “either of the alternatives” rather than the common parent, i.e. you don’t need to put the parent into a `throws` clause. – Holger Feb 22 '19 at 09:00
  • What type does the object "ex" have? – anton_rh Mar 29 '19 at 05:06
  • @anton_rh It has the type which is thrown by the try block. For example, If IOException occurs, ex refers for IOException class. – S_K Apr 20 '19 at 06:33
  • 2
    The choice of `|` for this is likely because it's the standard syntax for a union type in other languages. The language spec even calls it a "union", though it's only syntactically valid in this construct (as of Java 7): *"An exception parameter may denote its type as either a single class type or a union of two or more class types (called alternatives). The alternatives of a union are syntactically separated by |."* https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20 – kaya3 Nov 10 '19 at 23:39
  • Just a reminder, if you have to handle two exceptions differently where one is a subclass of another, ensure to have seperate Catch clases for the subclasses before the parent classes. – Jano Janahan Mar 03 '21 at 17:41
  • 1
    ``... if all the exceptions belong to the same class hierarchy, you can simply catch that base exception type.`` Not really. Doing so, you will catch all other - and maybe unwanted - children of the base type. Sementically, this is different. – spi Mar 30 '21 at 07:46
119

Not exactly before Java 7 but, I would do something like this:

Java 6 and before

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {
    
     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     

  } else {
    throw new RuntimeException(exc);
  }

}

Java 7
try {
  //.....
} catch ( IllegalArgumentException | SecurityException |
         IllegalAccessException| NoSuchFieldException exc) {
  someCode();
}
user454322
  • 7,300
  • 5
  • 41
  • 52
  • 12
    Note that your Java 6 example breaks the compiler's ability to tell what will be thrown from where. – MichaelBlume Feb 06 '13 at 19:39
  • 3
    @MichaelBlume True, which is not [ so ] bad. You can always get the original exception with `exc.getCause()`. As a side note, Robert C. Martin (among others) recommends to use unchecked exceptions (the compiler has no idea of what kind of exception will be thrown from there); refer to _Chapter 7: Error Handling_ on his book _Clean code_. – user454322 Feb 07 '13 at 17:49
  • 4
    In your Java 6 example shouldn't you be rethrowing the original exception instead of creating a new exception instance, i.e. `throw exc` instead of `throw new RuntimeException(exc)`? – David DeMar Mar 01 '14 at 14:29
  • Only if it is an instance of `RuntimeException`. I have updated the answer. =) – user454322 Mar 03 '14 at 04:06
  • 5
    This is pretty bad practice, from the perspective of readability. – Rajesh J Advani Dec 23 '14 at 05:54
  • 3
    Instanceof operation is bit costly, it's better to avoid as much as possible. – Paramesh Korrakuti Feb 16 '15 at 18:11
  • @user454322 This was awesomatic! – Emmanuel Angelo.R Apr 28 '15 at 11:52
  • Here in multi-catch approach, what would be the someCode() to expose which class has thrown the exception? As `instanceof` is bit costly like @ParameshKorrakuti mentioned, so not considerable. – Ram Aug 26 '18 at 18:45
  • 2
    `Exception`s are for **exceptional** cases. Exceptions are already expensive, `instaceof` being expensive shouldn't be a concern here... – user454322 Feb 22 '19 at 04:39
31

No, one per customer prior to Java 7.

You can catch a superclass, like java.lang.Exception, as long as you take the same action in all cases.

try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
    e.printStackTrace();
}

But that might not be the best practice. You should only catch an exception when you have a strategy for actually handling it - and logging and rethrowing is not "handling it". If you don't have a corrective action, better to add it to the method signature and let it bubble up to someone that can handle the situation.

With JDK 7 and later you can do this:

try {
    ...     
} catch (IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e) {
    someCode();
}
duffymo
  • 305,152
  • 44
  • 369
  • 561
  • 23
    Can I petition you to rephrase the portion about catching java.lang.Exception? I realize that it's an example, but I feel like some people might read this answer and say, "oh, okay, I'll just catch Exception then", when that's probably not what they want to (or should) do. – Rob Hruska Aug 16 '10 at 18:15
  • 2
    I knew about that, but I don't want to do it... Oh, well, guess I'm stuck with 4 catches then, till the next version of Java... – froadie Aug 16 '10 at 18:23
  • @duffymo: What's wrong with logging and rethrowing? Except that it clutters the code, its equivalent to not catching it, isn't it. Seen from the general error-handling strategy perspective. What's bad is logging and _not_ rethrowing. – Frank Osterfeld Aug 17 '10 at 13:35
  • 6
    I don't consider logging and rethrowing handling anything. I'd prefer to let it bubble up to someone who can do something meaningful. That last layer where exceptions should never escape (e.g. controllers in a web app) should be the one to log the error in that case. – duffymo Aug 17 '10 at 14:31
  • Am I the only one who finds it absurd that a log isn't automatically generated for me? It seems that we all have to write the same stupid logging message every time some piece of code might throw an exception. – ArtOfWarfare Nov 06 '13 at 18:49
  • 1
    Logging is the "hello world" of AOP. If it's that bothersome, write an aspect and be done with it once. – duffymo Nov 06 '13 at 19:04
  • @ArtOfWarfare: Where would you like your logging? Either you catch the exception and really handle it and then a line like `logger.log(e)` is an negligible overhead or you add some *informative* message (which no generator can do for you). Or you don't catch it and then there's no reason to log it (as it happens elsewhere). – maaartinus Feb 11 '14 at 11:34
  • Your post should be a qualified comment, as it in no way answers the question posed here. – Jaydev Jul 13 '16 at 11:23
  • Best way to destroy your exception handling purpose of code. – SHAHS Oct 13 '17 at 08:48
26

Within Java 7 you can define multiple catch clauses like:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}
rob
  • 6,147
  • 2
  • 37
  • 56
crusam
  • 6,140
  • 6
  • 40
  • 68
21

If there is a hierarchy of exceptions you can use the base class to catch all subclasses of exceptions. In the degenerate case you can catch all Java exceptions with:

try {
   ...
} catch (Exception e) {
   someCode();
}

In a more common case if RepositoryException is the the base class and PathNotFoundException is a derived class then:

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

The above code will catch RepositoryException and PathNotFoundException for one kind of exception handling and all other exceptions are lumped together. Since Java 7, as per @OscarRyz's answer above:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}
Albert Rothman
  • 998
  • 2
  • 9
  • 27
Michael Shopsin
  • 2,055
  • 2
  • 24
  • 43
  • 7
    BTW catch clauses are handled in order so if you put a parent exception class before a child class then it's never called eg: try { ... } catch (Exception e) { someCode(); } catch (RepositoryException re) { // never reached } – Michael Shopsin Aug 16 '10 at 18:14
  • 4
    Actually precisely because it can never be reached, such code doesn't even compile. – polygenelubricants Aug 17 '10 at 06:11
11

A cleaner (but less verbose, and perhaps not as preferred) alternative to user454322's answer on Java 6 (i.e., Android) would be to catch all Exceptions and re-throw RuntimeExceptions. This wouldn't work if you're planning on catching other types of exceptions further up the stack (unless you also re-throw them), but will effectively catch all checked exceptions.

For instance:

try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    } 
}

That being said, for verbosity, it might be best to set a boolean or some other variable and based on that execute some code after the try-catch block.

Oleg Vaskevich
  • 12,444
  • 6
  • 63
  • 80
4

In pre-7 how about:

  Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }
Bill S
  • 49
  • 1
4

For kotlin, it's not possible for now but they've considered to add it: Source
But for now, just a little trick:

try {
    // code
} catch(ex:Exception) {
    when(ex) {
        is SomeException,
        is AnotherException -> {
            // handle
        }
        else -> throw ex
    }
}
Dr.jacky
  • 3,341
  • 6
  • 53
  • 91
4

It is very simple:

try { 
  // Your code here.
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
            NoSuchFieldException e) { 
  // Handle exception here.
}
0

Catch the exception that happens to be a parent class in the exception hierarchy. This is of course, bad practice. In your case, the common parent exception happens to be the Exception class, and catching any exception that is an instance of Exception, is indeed bad practice - exceptions like NullPointerException are usually programming errors and should usually be resolved by checking for null values.

Community
  • 1
  • 1
Vineet Reynolds
  • 76,006
  • 17
  • 150
  • 174
0

in Kotlin, this way can be useful:

var result = false
       
            try { ...
                   result=false

                    }catch (ex:Exception ){

                when (ex) {
                    is SocketTimeoutException,
                    is NetworkOnMainThreadException,
                    is UnknownHostException,
                    is IllegalThreadStateException -> result=false
                    else -> throw ex
                }
                
                 }
Mori
  • 2,653
  • 18
  • 24