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).
Related
Can anyone please explain me code attached.How the control will transfer from try to finally and how finally will work without return statement.
class TryCatchFinally{
int ID = 0;
public Integer test() {
try {
return this.ID;
} finally {
this.ID = 2;
}
}
public static void main(String ...s) {
TryCatchFinally obj = new TryCatchFinally(); //line 1
System.out.println(obj.test()); //line 2
//line 3
}
}
Actual output is -
0
While executing test() function, I have changed the value of ID in finally as 2. I know if I write the obj.ID at line no#3 in main method output will be 2 for line no#3. I would like to know here, I got result as 0 for line no#2. Why? When finally actually been called here?
The finally block does occur. From the docs tutorial:
This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break.
However the result gets "returned" (The method isn't exited, but the return value is stored temporarily) before the finally block is reached, so at the time of the return statement, ID is still zero.
public Integer test() {
try {
return this.ID; //Still 0 at time of return
} finally {
this.ID = 2; //This still gets executed, but after the return value is stored
}
}
If you print out the ID field after the method:
TryCatchFinally obj = new TryCatchFinally(); //line 1
System.out.println(obj.test());
System.out.println(obj.ID);
Then you get:
0
2
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;
}
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.
I would like to retry calling a function in the exception clause like this:
private int mTries = 0;
private void myFunction() {
try {
// do something
} catch (Exception e) {
if (mTries ++ < MAX_TRIES;
myFunction();
}
}
}
My question, regardless the stack memory usage, calling a function recursively in the catch clause the same as calling it in normal case? I am wonder if doing this will blow off the stack, if my app is running on android platform.
private void anotherFunction(int i) {
if (i == 0)
return;
anotherFunction(i--);
}
Why not write it like this?
private void myFunction(){
int triesRemaining = MAX_TRIES;
while( triesRemaining-- > 0 ){
try{
// ... do stuff
return;
}
catch( Exception e ){
}
}
throw new Exception( "too many failures" );
}
However, I seriously recommend you narrow down the catch clause so that you only catch only those types of exception after which you'd want to continue processing.
Your second implementation will always cause a stack overlflow. (Try passing in a value even of 1, it will fail).
My question, regardless the stack memory usage, calling a function recursively in the catch clause the same as calling it in normal case?
Yes, it is exactly the same.
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.