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.
Related
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 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).
Is there a way to end the method that calls on the method that the code is in. Let me explain if you have some code like this.
int value;
value = method();
value = 3;
If I got it work like I want then the execution of the code would end on line 2 and line 3 would never be executed. basically it would be like there was a return between line 2 and 3. Is is something like this possible with Java?
Edit: Ok i think a lot of people have misunderstood me. The code that end the code on in this method on line 2 should be inside of method() and it should not be possible to avoid this outside this method if it's call inside of a try for example.
Your example is a bit abstract, a real one might result in better answers. In general though there are two ways this is normally achieved:
Return a special value e.g. -1
int method() {
if (/* something is wrong */) {
return -1;
}
// Process as normal and return real value
}
...
int value;
value = method();
if (value == -1) {
value = 3;
}
Throw an exception in method()
int method() throws IllegalStateException {
if (/* something is wrong */) {
throw new IllegalStateException();
}
// Process as normal and return real value
}
...
int value;
try {
value = method();
} catch (IllegalStateException e) {
value = 3;
}
You can terminate the current program / JVM with System.exit
java.lang.System.exit(0 /* Status */ );
If you don't want to exit then you have to use return.
in a void method do
int value;
value = method();
return;
Or if method has the same return signature as the current method
int value;
return value = method();
Add if condition value=youexpected return;
I read code from one book and have this method:
public int getScore(String name) {
try {
//some code here
return score;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
Why this method in catch returns -1? Why not 5? Is that some convention?
-1 is a standard error code when the caller expects a positive int
but really in that case a wrapped RuntimeException or a more specific one would have been much better
I'm assuming the author uses this code to make sure something gets returned, and the caller of getScore can check to see if a score was correctly called.
In code:
int theScore = getScore("My Name");
if(theScore == -1) {
// Oh no, there was an error!
}
We can use the check for -1 to make sure that the code knows when getScore fails.
Why method returns -1?
Because it is very poorly designed to do so on any exception. The method would have been better designed by declaring it to throw the exception(s) of interest and specifically by not catching all the RuntimeExceptions as well.
You are the one choosing what you want to return as you are the only one who knows how you want to handle that returned value. I personally use -1 too when I want to detect an error, and I know a lot of people doing the same.
The reason they picked -1 instead of 5 is because -1 is not a feasible score to return from the getScore method. Therefore, when you call the function, you can easily check if it was -1 returned or not.
If it was a function that could realistically return -1 for a successful run, -1 would be a poor choice of a flag indicator. A more appropriate choice, then, might be -9999 or something ridiculous.
The first problem is we don't know what the exceptions are. Catching every exception is a very poor decision. Those exceptions were thrown for a reason so you would know exactly what went wrong and can deal with it appropriately.
Bad:
public int getScore(String name) {
try {
int score = scores.getScoreForName(name);
return score;
} catch (Exception e) { // catches everything
e.printStackTrace();
return -1;
}
}
Marginally better...
public int getScore(String name) {
try {
int score = scores.getScoreForName(name);
return score;
} catch(NameNotFoundException) {
e.printStackTrace();
return -2; // now we know what happened, not just a general error
} catch (Exception e) { // catches everything
e.printStackTrace();
return -1; // generally error
}
}
Much better:
/**
* Get the score for a given name. Will throw a runtime exception if the
* name doesn't exist.
* #param name The name to get the score for
* #return the score for the name
* #throws NameNotFoundException if the name doesn't exist in the database.
*/
public int getScore(String name) {
return scores.getScoreForName(name);
}