Catch handler for multiple exceptions? - java

I am experimenting with exceptions and i want to ask when it is possible to handle multiple exceptions in one handler and when it is not?
For example i wrote the following code which combines two exceptions (FileNotFoundException OutOfMemoryError) and the program runs properly without any error. Al thought the handling is not so relevant with the functionality of the code i chose them just to see when i can combine multiple exceptions in on handler :
import java.io.FileNotFoundException;
import java.lang.OutOfMemoryError;
public class exceptionTest {
public static void main(String[] args) throws Exception {
int help = 5;
try {
foo(help);
} catch (FileNotFoundException | OutOfMemoryError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean foo(int var) throws Exception {
if (var > 6)
throw new Exception("You variable bigger than 6");
else
return true;
}
}
But when i choose different type of exceptions the compiler gives me error . For example when i choose IOException and Exception i have the error the exception is already handled " :
import java.io.IOException;
import java.lang.Exception;
public class exceptionTest {
public static void main(String[] args) throws Exception {
int help = 5;
try {
foo(help);
} catch (IOException | Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean foo(int var) throws Exception {
if (var > 6)
throw new Exception("You variable bigger than 6");
else
return true;
}
}
So why is this happening ? Why in one occasion i can use multiple exception in handler and in the other not ? Thank you in advance.

You are getting the message because IOException is a subclass of Exception. Therefore, if an IOException were thrown, it would be caught by a catch (Exception e) statement, so catching it as an IOException is redundant.
The first example works because neither FileNotFoundException nor OutOfMemoryError is a subclass the other.
However, you can catch sub-classed exceptions using the separate catch statement:
try{
// code that might throw IOException or another Exception
} catch (IOException e) {
// code here will execute if an IOException is thrown
} catch (Exception e) {
// code here will execute with an Exception that is not an IOException
}
If you do this, please note that the subclass must come first.

Related

Java exception handling with instantiate Exception superclass and IOException subclass

First I create a class called OrderHandler.java. I declared an instance of superclass Exception and an instance of subclass IOException in a main method.
Now the question is to show a compilation error when you try catching the superclass exception type before the subclass exception type. What should I do? Need I create some methods to show the path? Or do I need to instantiate the OrderHandler as well?
Thanks
import java.io.IOException;
public class OrderHandler {
public static void main(String[] args) {
// TODO Auto-generated method stub
Exception A = new Exception();
IOException B = new IOException();
}
}
You're not catching any exceptions in your sample code. I think you mean this:
try {
// do some stuff
} catch (Exception ex) {
// report a general exception
} catch (IOException ex) {
// report an IO exception
}
This isn't going to do what you want it to do. You need to catch more specific exceptions first, otherwise the IOException block will never execute. The correct way to do this is:
try {
// do some stuff
} catch (IOException ex) {
// report an IO exception
} catch (Exception ex) {
// report a general exception
}

Try-Catch-Finally Block

i already know that the traditional Try block in java must have at least catch block or finally block (both or either), and i already know that checked exceptions must be handled or declared.
but i am wondering why it won't compile although i have used correct try block syntax
i have this piece of code here , in the main method i used Try with finally block but i am wondering why it won't compile
Here is my code:
import java.io.IOException;
import java.net.Socket;
public class ExHandling {
public void connect() throws IOException
{
Socket s = new Socket();
try
{
s.getInputStream();
}
catch(IOException e )
{
e.printStackTrace();
}
finally
{
s.close();
}
}
public static void main(String []args)
{
ExHandling ex = new ExHandling();
try
{
ex.connect();
}
finally
{
System.out.println("Finally");
}
}
}
Any Help Please
Remove the throws clause from your connect() method. It already catches the IOException. If you declare your method as throwing a checked exception it must be caught upon calling.
Update: since Socket#close() can itself throw an exception, you need to decide what do you want to do about it. Exception handling is hard because people tend to only think about the happiest path a program can take.
If you don't want to catch the exception explicitly in the main() method, you have only one choice: wrap the call to s.close() (and every other method that can throw a checked exception) into its' own try-catch block and remove the throws clause:
public void connect() {
Socket s = new Socket();
try {
s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
But you should probably think—"what should I do when it fails?"—each time you're dealing with code that might throw.
Either catch the thrown IOException or throw it and let JVM handle the same.
IOException checked exception so you need catch or add an exception to a signature method. final just guarantee whatever happens final block will be executed.
Declare your main method to catch the IOException. If you do so, when the exception is thrown in your connect() method, it will be propagated to the main method and your finally block will be executed. If that is what you wanted.
finally itself cannot handle any exception. So when using try{} finally then the code inside try should either not be raising any exception or your method must be throwing the exception.
It won't compile because just as you indicated, the s.close() in your finally block can throw an IOException and you chose to handle that checked exception by specifying the "throws IOException" clause. Because of that choice, the calling method must handle that checked exception by either catching it or also specifying it will throw the exception.
It is unclear what results you desire other than it must compile, so here are three options:
1) Wrap s.close with it's own try/catch and remove the throws clause.
2) Move "ExHandling ex" definition inside the caller's try/catch.
3) Add a throws clause to the caller (and remove the try/finally if desired). RECOMMENDED
CAUTION: You really don't want to catch an exception and do "e.printStackTrace();". All this does is mask issues in your logic. You should only catch an exception if you plan to handle it in some manner; otherwise, you should allow the exception to propagate up the chain of callers. Thus, only use options 1 & 2 if you really wish to do something in all the catch clauses.
Option 1: Wrap s.close with it's own try/catch and remove the throws clause.
public void connect() {
Socket s = new Socket();
try {
s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExHandling ex = new ExHandling();
try {
ex.connect();
}
finally {
System.out.println("Finally");
}
}
Option 2: Move "ExHandling ex" definition inside the caller's try/catch. In this case I would recommend using try with resources for the socket.
public void connect() throws IOException {
Socket s = new Socket();
s.getInputStream();
s.close();
}
public static void main(String[] args) {
try {
ExHandling ex = new ExHandling();
ex.connect();
} catch (IOException e) {
e.printStackTrace();
}
finally {
System.out.println("Finally");
}
}
Option 3: Add a throws clause to the caller (and remove the try/finally if desired). RECOMMENDED
public void connect() throws IOException {
Socket s = new Socket();
s.getInputStream();
s.close();
}
public static void main(String[] args) throws IOException {
ExHandling ex = new ExHandling();
ex.connect();
System.out.println("Finally");
}

Compiler forces to handle rethrow of unchecked exception

I have encountered a scenario while working with exceptions, following is the sample code.I am trying to understand why following code fails to compile. I am checking the exception type before rethrow which is unchecked exception.
public class TestException {
public void test() throws FileNotFoundException {
FileReader test = new FileReader("");
}
public static void main(String[] args){
TestException test=new TestException();
try {
test.test();
} catch (Exception e) {
// TODO Auto-generated catch block
if(e instanceof ArithmeticException){
throw e;
}
else{
e.printStackTrace();
}
}
}
}
You are still throwing a reference variable e of type Exception. Exception is a checked type. The compiler only knows the reference variable's type, not the referenced object's. If you want to keep main's method signature as-is, you'll need to either wrap e into an unchecked exception type (such as ArithmeticException):
if(e instanceof ArithmeticException){
throw new ArithmeticException(e.getMessage());
}
or cast it as an unchecked exception:
if(e instanceof ArithmeticException){
throw (ArithmeticException)e;
}
Since the reference variable e is of type java.lang.Exception, throw e will throw checked exception. Thus it has to be declared in throws section in the method signature.
Try changing your catch block as follows:-
if(e instanceof ArithmeticException){
throw (ArithmeticException)e;
}
else{
e.printStackTrace();
}
You could also use a hack with Generics to throw an checked Exception as an unchecked one:
http://www.gamlor.info/wordpress/2010/02/throwing-checked-excpetions-like-unchecked-exceptions-in-java/
I like to use this over throw new RuntimeException(e), since the latter creates unnecessary output in a Stacktrace and its harder to catch somewhere else (you have to check the cause instead of the excetion itself).
catch (Exception e) {
Here is the effective declaration of e.
if(e instanceof ArithmeticException){
Here you are doing a runtime check of the type of e.
throw e;
At this point the compile-time type of e is Exception. So the compiler enforces its rules.
I will suggest to use two catch blocks.
typechecking in catch block is not a good practice where you can catch that specific class using other catch statement.
catch (ArithmeticException e) {
// TODO Auto-generated catch block
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
#Silly Freak I agree with you.
If you throw any exception then you should handle it but in your program your are able to throw but nowhere you are handling the exception, so just handle the exception by adding throws in main class like this:-
package first;
import java.io.FileNotFoundException;
import java.io.FileReader;
class A3{
public void test() throws FileNotFoundException {
FileReader test = new FileReader("");
}
public static void main(String[] args) throws Exception{
A3 test=new A3();
try {
test.test();
} catch (Exception e) {
// TODO Auto-generated catch block
if(e instanceof ArithmeticException){
throw e;
}
else{
e.printStackTrace();
}
}
}
}

catch multiple exceptions at once in java?

import java.io.*;
class West1 extends Exception {
private String msg;
public West1() {
}
public West1(String msg) {
super(msg);
this.msg=msg;
}
public West1(Throwable cause) {
super(cause);
}
public West1(String msg,Throwable cause) {
super(msg,cause);
this.msg=msg;
}
public String toString() {
return msg;
}
public String getMessage() {
return msg;
}
}
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
}catch(West1 ce) {
System.out.println(ce.getMessage());
//throw new NumberFormatException();
throw new FileNotFoundException();
}catch(FileNotFoundException fne) {
fne.printStackTrace();
}/*catch(NumberFormatException nfe) {
nfe.printStackTrace();
}*/
}
}
In the above code, NumberFormatException is thrown from catch block it compile and run successfully but when FileNotFoundException is thrown from catch block it will not compile. Following Errors are thrown:
West.java:40: error: exception FileNotFoundException is never thrown in body of
corresponding try statement
}catch(FileNotFoundException fne){
West.java:39: error: unreported exception FileNotFoundException; must be caught
or declared to be thrown
throw new FileNotFoundException();
So my question is what is reason behind this behaviour?
NumberFormatException is a RuntimeException, meaning that it's not required to be declared in all methods it may be thrown. This means that, unlike FileNotFoundException, the compiler can not know if it can get thrown in a block or not.
The title implies you are trying to catch multiple exceptions at once, and your code implies you understand that you can have multiple catch blocks for a single try block to catch different types of exceptions. Everything is good so far, but you seem to misunderstand exactly where the try-catch catches errors.
Here is you code. I removed the comments to make it more concise.
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
} catch(West1 ce) {
System.out.println(ce.getMessage());
throw new FileNotFoundException(); // <-- Must be caught
} catch(FileNotFoundException fne) { // <-- Never thrown
fne.printStackTrace();
}
}
}
The first compiler error is because the catch block that is for catching FileNotFoundException's try block never throws FileNotFoundException. The second compiler error is because FileNotFoundException is a checked exception. Because it is a checked exception your code must either
handle it (by catching it with try-catch)
let everyone know it could throw it (public static void main(String[] args) throws FileNotFoundException { ...).
From the context of your code, you seem to be going with the first option, handling it with try-catch, but you have the catch in the wrong place.
catch blocks don't catch exceptions, try blocks do. catch blocks specify what to do with the actual caught exception.
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
} catch(West1 ce) {
System.out.println(ce.getMessage());
try {
throw new FileNotFoundException();
} catch(FileNotFoundException fne) {
fne.printStackTrace();
}
}
}
}
Try that instead. Notice how you can have a try instead of a catch. This wouldn't matter if FileNotFoundException wasn't a checked exception.

Exceptions works correct but not how its must

The method processExceptions() should call the method BEAN.methodThrowExceptions and handle exceptions:
1.1. if an exception FileSystemException occurs, then log it by calling the method BEAN.log and throw forward
1.2. if an exception CharConversionException or any other IOException occurs, just log it by calling the method BEAN.log
Add the class/type of the exception you are forwarding in 2.1. to the processExceptions() method signature.
Handle the remaining exception in the method main() and log it. Use try..catch
I tried different solutions. It works but not as it should. What is the correct placement of throws in methods. Or maybe i shouldnt use them at all? And if I don't place them I can't make use of throw. Please help, I would really appreciate your time.
public class Solution {
public static StatelessBean BEAN = new StatelessBean();
public static void main(String[] args) {
try{
processExceptions();
}
catch (CharConversionException e){
BEAN.log(e);
}
}
public static void processExceptions()throws CharConversionException {
try{
BEAN.methodThrowExceptions();
}
catch (CharConversionException e){
BEAN.log(e);
throw e;
}
catch (FileSystemException e){
BEAN.log(e);
}
catch (IOException e){
BEAN.log(e);
}
}
public static class StatelessBean {
public void log(Exception exception) {
System.out.println(exception.getMessage() + ", " + exception.getClass().getSimpleName());
}
public void methodThrowExceptions() throws CharConversionException, FileSystemException, IOException {
int i = (int) (Math.random() * 3);
if (i == 0)
throw new CharConversionException();
if (i == 1)
throw new FileSystemException("");
if (i == 2)
throw new IOException();
}
}
}
If a method is capable of throwing an exception which IS NOT RuntimeException (either directly throwing or invoking a method which can throw an exception), it should either handle the exception or declare that it throws the exception, so that any other method which calls this method would know that it can encounter an exception and can either handle it or declare it that it throws (and so on).
Since you are dealing with checked exception, there is no clean way to avoid declaring throws, but there is a (messy) workaround. You can wrap the exception in a RuntimeException and can throw it and when you want to handle it, you can get the actual exception from the re.getCause();
public class Solution {
public static StatelessBean BEAN = new StatelessBean();
public static void main(String[] args) {
try{
processExceptions();
}
catch (RuntimeException re){
if (!(re.getCause() instanceof CharConversationException)) {
//handle the case in which the exception was not CCE and not FSE not IOException
}
}
}
public static void processExceptions() {
try{
BEAN.methodThrowExceptions();
} catch (CharConversionException cce){
BEAN.log(e);
throw new RuntimeException(cce);
} catch (FileSystemException fse){
BEAN.log(e);
} catch (IOException e){
BEAN.log(e);
}
}
public static class StatelessBean {
public void log(Exception exception) {
System.out.println(exception.getMessage() + ", " + exception.getClass().getSimpleName());
}
public void methodThrowExceptions() throws CharConversionException, FileSystemException, IOException {
int i = (int) (Math.random() * 3);
if (i == 0)
throw new CharConversionException();
if (i == 1)
throw new FileSystemException("");
if (i == 2)
throw new IOException();
}
}
}
I am not sure whether I understood your question correctly and this is what you wanted :)
I think that the order:
Handle the remaining exception in the method main()
means that you should catch not only CharConversionException, but all other Exceptions by:
catch (Exception e)
Besides, you should ask it on help.javarush.net I think :>

Categories

Resources