Java exception handling with instantiate Exception superclass and IOException subclass - java

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
}

Related

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();
}
}
}
}

Java7 multiple exception handling

I have been trying to find out answer to this question but did not get any satisfactory explanation. Here is some background:
Java 7 allows us to catch multiple exceptions in a single catch block provided those exceptions are from diffrent hierarchy. Eg:
try {
// some code
} catch(SQLException | FileNotFoundException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
But if exceptions are from the same hierarchy we must use multiple catch blocks like:
try {
// some code
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
But if I try to write code like below compiler complains that "The exception FileNotFoundException is already caught by the alternative IOException"
try {
// some code
} catch(FileNotFoundException | IOException e) { // compiler error
e.printStackTrace();
}
Now my question is: Why compiler reports an error in last case, can't it figure out that FileNotFoundException is special case of IOException? This would save code duplication when my exception handling logic is same.
Why compiler reports an error in last case, can't it figure out that FileNotFoundException is special case of IOException?
Because FileNotFoundException is a subclass of IOException. In other words, the "FileNotFoundException |" part is redundant.
The reason why the code below is ok...
} catch(FileNotFoundException e) {
...
} catch(IOException e) {
...
}
...is because here the IOException clause matters: If a SocketException is thrown for instance, it will pass the by the FileNotFoundException part, and get caught in the IOException clause.
When catching an exception you have order your catch clauses from the most specific to the most general.
Consider the following hierachy:
class MyException extends Exception {}
class MySubException extends MyException {}
If a part of your code throws MyException an an other part throws MySubException you have to catch MySubException first.
catch(MySubException e){
} catch(MyException e){
}
Its the same thing like using the instanceof operator.
If you test if an instance of MySubException is an instanceof MyException the result will be true.
mse = new MySubException();
if(mse instanceof MyException){
println("MyException");
} else if(mse instanceof MySubException){
println("MySubException");
}
This piece of code will never print "MySubException".
mse = new MySubException();
if(mse instanceof MySubException){
println("MySubException");
} else if(mse instanceof MyException){
println("MyException");
}
This would be the correct order.
Its because FileNotFoundException extends IOException, as you said its of same hierarchy, you cannot add them to same catch block.

Catch handler for multiple exceptions?

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.

Call constructor from constructor and catch exceptions

I have a constructor which calls another constructor in the same class. The problem is I want to catch Exceptions and throw them onwards to the method that called the first constructor. Yet Java doesn't allow this as the constructor call must be the first statement in the constructor.
public Config(String fn) throws IOException, ExcFormattingError {
theFile = fn;
try { cfRead(); }
catch(FileNotFoundException e) {
//create a new config with defaults.
theConfig = defaultConfig();
create();
} catch (IOException e) {
throw new IOException(e);
} catch (ExcFormattingError e) {
throw new ExcFormattingError();
}
fixMissing(theConfig);
}
public Config() throws IOException, ExcFormattingError {
try {
//Line below is in error...
this("accountmgr.cfg");
} catch (IOException e) {
throw new IOException(e);
} catch (ExcFormattingError e) {
throw new ExcFormattingError();
}
}
If someone could explain how I could do this that would be good. A bonus would be knowing why the language has to behave this way, because that is always interesting.
You don't need those try-catch block inside the constructor (in fact, you can't write it there, as you already figured out). So, change your constructor to:
public Config() throws IOException, ExcFormattingError {
this("accountmgr.cfg");
}
In fact the catch block in your constructor was hardly doing anything productive. It was just re-creating an instance of the same exception, and throwing it. That is really not needed given the fact that, if the exception is thrown, it will automatically propagated to the caller code, where you can handle the exception.
public void someMethod() {
Config config = null;
try {
config = new Config();
} catch (IOException e) {
// handle it
} catch (ExcFormattingError e) {
// handle it
}
}
Having said that, it is rarely a good idea to throw a checked exception from the constructor, even worse handling them in the caller code.
If the exception is thrown, and you handle it in the calling method. Then you are simply ignoring the fact that your instance is not completely initialized. Proceeding with that instance further will result in some unexpected behaviour. So, you should avoid it really.

Categories

Resources