Understanding the Try Catch block behavior - java

I ran into a strange problem with try catch which got me doubting about my own realization of exception handling fundamentals. As per the basic syntax
try{
code to be checked
}
catch(Exception e){}
finally{}
However the code below gives me a null pointer exception which I believe should have been caught.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
try{
for(Model m: Null Collection coming from DB)
System.out.println("Inner Block");
System.out.println("Outer Block");
}catch(Exception e){}
}
}

The following snippet prints "An exception!"
List<String> strings = null;
try {
for (String s : strings) {
System.out.println(s);
}
} catch (Exception e) {
System.out.println("An exception!");
}
And as others have pointed out, and you stated yourself, Runtime exceptions are caugth by Exception catches
Have you tried recompiling all your code from scratch? In my team (250.000 lines codebase) using eclipse we sometimes have trouble with bad compiles that can give unexplainable problemes like this. We usually solve them by a complete recompile.

Are you sure about your issue? I believe there's some clean-up code in your catch which hasn't been initialized yet - hence the exception. Would help if you post your actual code.
The following works as expected:
import java.util.List;
public class Main {
public static void main(String[] args) {
List i=null;
try{
for(Object o: i) {
System.out.println("Inner Block");
}
System.out.println("Outer Block");
}catch(Exception e){}
}
}

Understanding the Try Catch block behavior?
The main reason to use try-catch block is to handle something will goes wrong with your code or something you are unexpected for the normal case and something will throw an exception somehow and to handle it in catch block, and the finally block is used almost to close any opened stream and it will run every time in the code even if the try or catch returned any value (except for system termination).
In your code it seems that there is something you get it from database which is null or not initialized yet or it is already returned from database of null value, Now you cannot use null object if it's not initialized already! you have to insure if it's null or not then use it like this:
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
try {
if(Null Collection coming from DB != null){
for(Model m: Null Collection coming from DB)
System.out.println("Inner Block");
}
System.out.println("Outer Block");
} catch (Exception e) {}
}
}
The NullPointerException is extends RuntimeException and it's thrown when you try to use a null object.

i has not been initialized,
public class Ideone{
public static void main (String[] args) throws java.lang.Exception
{
int i = 0;
try{
if(i<2)
System.out.println("Inner Block");
System.out.println("Outer Block");
}catch(Exception e){}
}
}

Cannot reproduce.
I tried this
public static void main (String[] args) throws java.lang.Exception
{
Collection c = null ;
try{
for(Object i:c)
System.out.println("Inner Block");
System.out.println("Outer Block");
}catch(Exception e){}
}
It works well.

Related

Constructor in the Try/Catch block

The question is about the result of the below code. The answer is compilation error. However I really do not understand why we can't have constructor in try/catch block. I will put the the code below:
public class Test {
try {
public Test() {
System.out.println("GeeksforGeeks");
throw new Exception();
}
}
catch(Exception e) {
System.out.println("GFG");
}
public static void main(String [] args) {
Test test= new Test();
}
}
Because the assignments are statements and statements are allowed only inside blocks of code(methods, constructors, static initializers, etc.)
here's the clean code
public class Test {
public Test()throws Exception {
System.out.println("GeeksforGeeks");
throw new Exception();
}
public static void main(String [] args) {
try {
Test test= new Test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Because a constructor is a declaration, not a statement.
Your constructor can be called by other code, but merely declaring it does not execute it; that’s what new Test() does. Nothing is executed merely by declaring the constructor, so there is nothing that can throw an exception. Thus, there is nothing to catch.
In more general syntax terms, statements which don’t evaluate to a value can only exist in constructors, methods, and initialization blocks.
You can, however, do this:
public static void main(String[] args) {
try {
Test test = new Test();
} catch (Exception e) {
System.out.println(e);
}
}
new Test() actually executes the constructor, which is why it may throw an exception and thus you can legally attempt to catch any exception it may throw. Syntactically, all of the above code is inside a method (the main method), which is allowed.

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

Getting compilation error in main even though try catch finally block is added in the calling method

I am trying to run the below code but getting compilaton error as "Unhandled exception type FileNotFoundException", as per my understanding this should not happen since try catch and finally blocks are added in the calling method.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Test
{
public static void main(String[] args)
{
myMethod();
}
public static void myMethod() throws FileNotFoundException
{
try
{
System.out.println("In the try block");
FileInputStream fis = new FileInputStream("file.txt");
}
catch(Exception e)
{
System.out.println("in the catch block");
throw e;
}
finally
{
System.out.println("in the finally block");
}
}
}
Remove throws FileNotFoundException from the myMethod signature (and then you'll need to remove throw e; from the catch block).
Or, add a try and catch to your main method (to handle the FileNotFoundException that you have indicated myMethod can throw).
Or, add throws FileNotFoundException to the signature of main (as pointed out by Andreas in the comments).
In short, the compiler will not allow you to have a code path with checked exceptions that are not handled.
In the catch block, you are throwing the Exception again once you catch it. If you really want to throw it from the myMethod() even after catch it, just add another try-catch to the main method.
public static void main(String[] args){
try{
myMethod();
}catch(FileNotFoundException e){
System.out.println("catch block in main");
}
}
Or else if you want to just catch the Exception in your myMethod(), don't throw it back.
try{
System.out.println("In the try block");
FileInputStream fis = new FileInputStream("file.txt");
}
catch(Exception e){
System.out.println("in the catch block");
}
finally{
System.out.println("in the finally block");
}
you can read more about re-throwing exceptions in following question.
Rethrow exception in java

Exception Handling try without catch, but with finally [duplicate]

This question already has answers here:
Java Try Catch Finally blocks without Catch
(11 answers)
Returning from a finally block in Java
(6 answers)
Closed 6 years ago.
public class ExceptionTest {
public static void main(String[] args) {
ExceptionTest et = new ExceptionTest();
try {
et.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public int testMethod() {
try {
throw new Exception();
}finally {
return 4;
}
}
The above code is working fine, but when I change return type of testMethod() to void and changing the line return 4; to System.out.println("some print msg"); is causing compilation problem.
Can anybody please give solution for why it is giving compilation error?
The problem is that a return statement inside a finally block will cause any exception that might be thrown in the try block to be discarded.
When you remove the return from the finally then what the code is doing is to throw a checked exception which requires that you throw Exception or you catch it and this is the reason why there's a compiler error.
Look at
https://www.owasp.org/index.php/Return_Inside_Finally_Block
Returning from a finally block in Java
Does finally always execute in Java?
The behaviour of return in finally is described in Java Language Specification and is well explained here http://thegreyblog.blogspot.it/2011/02/do-not-return-in-finally-block-return.html
This code works in Java 8:
public class ExceptionTest {
public ExceptionTest() {
}
public static void main(String[] args) {
ExceptionTest et = new ExceptionTest();
try {
et.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public void testMethod() throws Exception {
try {
throw new Exception();
} finally {
//return 4;
System.out.println("hello finally");
}
}
}
The only compilation problem for me was the missing "throws Exception" in the method declaration.
This is the output:
hello finally
java.lang.Exception
at ExceptionTest.testMethod(ExceptionTest.java:17)
at ExceptionTest.main(ExceptionTest.java:9)

exception.getMessage() output with class name

I'm trying to fix an issue, in my application I have this code
try {
object1.method1();
} catch(Exception ex) {
JOptionPane.showMessageDialog(nulll, "Error: "+ex.getMessage());
}
and the object1 would do something like that:
public void method1() {
//some code...
throw new RuntimeException("Cannot move file");
}
I get a messsage in my option pane like this:
Error: java.lang.RuntimeException: Cannot move file
but I used getMessage and not toString method, so the name of the class shouldn´t appear, right?
What I am doing wrong?
I already tryied with a lot of exceptions, even Exception itself. I'm looking to solve this no without the need to implement my own Exception subclass
PROBLEM SOLVED - thank you all!
The try and catch were actually being called in get() method from SwingWorker which constructs an ExecutionException with my exception thrown from doInBackground()
I fixed doing this:
#Override
protected void done() {
try {
Object u = (Object) get();
//do whatever u want
} catch(ExecutionException ex) {
JOptionPane.showMessageDialog(null, "Error: "+ex.getCause().getMessage());
} catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Error: "+ex.getMessage());
}
}
I think you are wrapping your exception in another exception (which isn't in your code above). If you try out this code:
public static void main(String[] args) {
try {
throw new RuntimeException("Cannot move file");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
}
}
...you will see a popup that says exactly what you want.
However, to solve your problem (the wrapped exception) you need get to the "root" exception with the "correct" message. To do this you need to create a own recursive method getRootCause:
public static void main(String[] args) {
try {
throw new Exception(new RuntimeException("Cannot move file"));
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Error: " + getRootCause(ex).getMessage());
}
}
public static Throwable getRootCause(Throwable throwable) {
if (throwable.getCause() != null)
return getRootCause(throwable.getCause());
return throwable;
}
Note: Unwrapping exceptions like this however, sort of breaks the abstractions. I encourage you to find out why the exception is wrapped and ask yourself if it makes sense.
My guess is that you've got something in method1 which wraps one exception in another, and uses the toString() of the nested exception as the message of the wrapper. I suggest you take a copy of your project, and remove as much as you can while keeping the problem, until you've got a short but complete program which demonstrates it - at which point either it'll be clear what's going on, or we'll be in a better position to help fix it.
Here's a short but complete program which demonstrates RuntimeException.getMessage() behaving correctly:
public class Test {
public static void main(String[] args) {
try {
failingMethod();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private static void failingMethod() {
throw new RuntimeException("Just the message");
}
}
Output:
Error: Just the message

Categories

Resources