Unreachable statement when using return in finally? - java

This compiles:
class Ex1 {
public int show() {
try {
int a=10/10;
return 10;
}
catch(ArithmeticException e) {
System.out.println(e);
}
finally {
System.out.println("Finally");
}
System.out.println("hello");
return 20;
}
}
on the other hand this doesn't:
class Ex15 {
public int show() {
try {
int a=10/0;
return 10;
}
catch(ArithmeticException e) {
System.out.println(e);
}
finally {
System.out.println("Finally");
return 40;
}
System.out.println("hello");
return 20;
}
}
and gives unreachable statement System.out.println("hello"); error. why is it so?

The finally has a return so you are probably getting an unreachable code block error.
finally
{
System.out.println("Finally");
return 40;
}
System.out.println("hello"); // unreachable code
return 20;
This is actually a compile-time error in Java. See section 14.20.
It is a compile-time error if a
statement cannot be executed because
it is unreachable.

It's unreachable code. According to the compiler, System.out.println("hello"); can never be executed.
Beside that, DON'T EVER write return within a finally block. (see Hidden Features of Java for why you should not).
EDIT:
Yes, but what makes return in finally
do this?
It's not because it is in a finally block or something. Even if you'd remove the finally keyword, you will still get the error.
class ex15 {
public int show() {
int a = 10 / 0;
return 40;
System.out.println("hello");
return 20;
}
}
Obviously, if you return 40, there is no way you can execute the next line. finally just means "do always, no matter what". So.

When you put a "return" in the "finally" block, anything that comes after it will never be executed. The "return" statement ends the method right there.
You would get the same error if you put a System.out.println() in the first method, after the "return" statement in it.

You have a return in the finally block. This makes any statements after that unreachable. Also you have a return in the try block and again in the finally block. This doesn't make sense.

Related

Why value from inside of "try" is printed during catching the exception? [duplicate]

This question already has answers here:
Does a finally block always get executed in Java?
(51 answers)
Closed 5 years ago.
I have code like this:
class ExceptionTest{
public Integer divide(int a, int b) {
try {
return a/b;
}finally {
System.out.println("Finally");
}
}
}
public class Three {
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
try {
System.out.println(test.divide(10, 0));
}catch(Exception e) {
System.out.println("DIVIDED BY 0!");
}
}
}
When I run the code it prints:
Finally
DIVIDED BY 0!
Why is that? If there Exception has been caught shouldn't only "DIVIDED BY 0!" be printed?
EDIT:
I know that finally is always printed, but what I mean is that try-finally in the method called "divide" is called in try-catched block in main. So If exception is being caught why something from try in try-catch is printed? Even if my ExceptionTest class looks like this:
class ExceptionTest{
public Integer divide(int a, int b) {
System.out.println("Finally")
return a/b;
}
}
So there is no try-finally block and exception is being thrown and I still have
Finally
Divided by 0!
The Docs tell us about the finally-block
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.
So even if you divide by 0, which raises an Exception, the finally block will be reached.
The code within the finally block is always run, even if the code executes correctly. You need to use catch instead, which is only executed when an error occurs.
try { /* Runs first, and stops executing if an Exception's thrown. */ }
catch(Exception e) { /* Run whenever an Exception's thrown. */ }
finally { /* Always runs. */ }
You also need to make sure that you return a value from the catch clause. Something like
try {
return a / b;
} catch (ArithmeticException ae) {
System.err.println("Cannot divide by zero!");
return -1;
}

Returning null AFTER a try-catch block

I'm having some trouble understanding the implications of the code in my accessor method below. Eclipse's compiler is requiring that I have a return statement after my try-catch block. Does this mean that my getter method will always return null or will it return the item I'm trying to retrieve if it int i doesn't need to be caught by the IndexOutOfBoundsException?
public T get(int i)
{
try
{
return bag[i];
}
catch(IndexOutOfBoundsException e) //if(logiSize < i+1)
{
System.out.println("Collection has fewer items than the index you entered!");
System.out.println("Returning null"); //or should I...?
}
return null;
}
Can anyone help me understand the implications here? Thanks so much!
Your method will return bag[i] unless you have an IndexOutOfBoundsException exception executing the return statement. In that case, they exception is caught, and since you're not throwing another exception inside the catch black. The method will proceed to return null.
If you only need to check for bounds, you could do this:
public T get(int i, T[] bag) {
if(i < bag.length) {
return bag[i];
}
return null;
}

How to make sure a piece of code runs before a method exits

I have a method with if-else cases, and more than one return statement, depending on the exact flow.
I have one line of code that needs to happen just before the return statement (e.g. releaseResources).
I want to be sure that this line is executed no matter what.
Is there a nice way of doing that in java?
Something that will make sure a piece of code is executed before leaving a closure?
What you are looking for is a try-finally block. Here is an example:
public Something someMethod() {
try {
if(someStatement) {
return new Something();
} else {
return new SomethingElse();
}
} finally {
// this is always executed, even if there is an Exception
}
}
The question is if this is really what you want. It sounds like your code might actually be better (more readable) if it has two methods. Like this:
public Something createSomething() {
if(someStatement) {
return new Something();
} else {
return new SomethingElse();
}
}
public Something someMethod() {
Something something = createSomething();
// Do the thing that always needs to be done
return something;
}
This separates the things you are doing into two methods. Now if the problem is that the first method can throw an exception and you want to do something nonetheless, you can still use a finally. But it might be better to capture and handle the Exception.
Also: You've noted that you want to close a resource. In that case I would suggest you look into try-with-resources:
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
An example here:
private String someMethod() throws IOException {
// Java automatically closes the following Readers:
try (BufferedReader br =
new BufferedReader(new FileReader("/path"))) {
return br.readLine();
}
}
Depending of the programming language you're using, the try-catch-finally exist:
Example from other post about launch code after the if-else
Finally statement will launch when try-catch condition ends
SORRY FOR EDIT
You can use a try/finally block, if that's what you really want.
try {
if (...) return ...;
else if (...) return ...;
else return ...;
} finally {
doSomething();
}
The code in the finally block will always be executed when you leave the try block, in particular at any return statement.
The finally block will always be executed even if an Exception is thrown.
try {
...
if () {
return;
else {
return;
}
} finally {
// Release resources
}
One of the main programming good practices is that each method should have one and only one return statement. If you have many possible values, you tend to keep the value in an object and return it at the end.
E.g:
public int func(boolean condition) {
if(condition) {
return 1;
} else {
return 0;
}
}
should be made like this
public int func(boolean condition) {
int num;
if(condition) {
num = 1;
} else {
num = 0;
}
return num;
}
As you can probably see, it's quite simple to ensure you call your method before return this way, adding it right before the only return.

Why is a "finally" block required in this code

I am aware that it is valid to create a try-catch segment without a
finally block. So in hacking around with this code, I can't figure out
what java logic (e.g. rule, theory) forces me to include a finally block
in this segment of code - and why the finally block has to include a return
statement in it. In other words, if I remove the finally
block completely I receive an error, and if I replace the return statement
in the finally block with anything else (e.g. System.out.printl(''foo")), I
still receive an error insisting that I include a return statement. Again,
the code as written here compiles and runs fine. I'm just trying to understand
a little bit of the theory behind the try-catch-finally construct (p.s. I understand
that its all about "exception handling"... but my question is really more about
code flow and the return statement).
class foo {
int getInt() {
try {
String[] students = {"student1", "student2"};
System.out.println(students[4]);
}
catch (Exception e) {
return 10;
}
finally {
return 20;
}
}
public static void main(String args[]) {
foo classSize = new foo();
System.out.println(classSize.getInt());
}
}
Consider the execution paths without the finally
int getInt() {
try {
String[] students = {"student1", "student2"};
System.out.println(students[4]);
// no return
}
catch (Exception e) {
return 10; // if an exception occurs
}
// no return
}
So what happens if no exception is thrown? You won't have a return value.
You can either provide a finally and put a return there or you can put a return outside the try-catch block.
Note that the finally in your try-catch-finally block has a return statement that will supersede the catch's return statement since a finally block is always executed if its associated try[-catch] is executed. You may want to go with the following
int getInt() {
try {
String[] students = {"student1", "student2"};
System.out.println(students[4]);
// the return could be here as well
}
catch (Exception e) {
return 10; // in case of failure
}
return 20; // in case of success
}
All execution paths must end up returning a value (or throwing an exception).

Which will be returned in a program

I was wondering what will be returned in a java program when you have multiple returns in a program.
private int numberReturner()
{
if (a) return a;
else if (b) return b;
for (int i = 1; i < board.size()-1; i++)
{
if (c) return c;
}
return d;
}
So lets say a is true, (it should return a), but wouldn't it return d because that is the final line of code in the whole program? Why is this so?
Sorry if I worded this a bit strangely...
Once any 'return' statement is encountered the method will exit execution and return that value.
That method will return d only if no other return statement is encountered before reaching that last line.
Normally, the first "return" encountered will be the one returned. But if there is a "return" statement encountered in a finally block, the "return" in the finally block will be returned.
e.g.
private int m1(){
try{
return 1;
}finally{
return 2; //this will be returned instead
}
}
If you've already "returned" you are never going to hit the subsequent returns.
The method returns a because the return statement exits from the current method, and control flow returns to where the method was invoked. Please read more about different branching keywords in Java tutorial. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
Once a return statement is executed the method ends and if it is not void the return value is returned.
I know only one exception to this rule, and you have it with the finally statement.
Take this example:
public static void main(String[] args) {
System.out.println(test());
}
private static int test() {
try {
return 1;
} finally {
return 2;
}
}
in this case test() returns 2, because the finally statement in this case is always executed before exit the method.
The current execution thread will leave a method the first time it encounters a return statement (the notable exception to this rule is with try...finally blocks, where, once a return is encountered, the finally{...} block executes before leaving the method.

Categories