This question already has answers here:
Multiple returns: Which one sets the final return value?
(7 answers)
Closed 8 years ago.
I was going through a couple of questions that are often asked in job interviews (at least in my country - Switzerland), and I was quite unsure about the output of a block of code that is supposed to be tricky. It would be nice to hear what you think the correct answer is.
here it is :
 public class LanguageTest12 {
public static void main(String... args){
System.out.println(foo());
}
private static int foo() {
int a = 1, b = 2;
try {
return a+b;
} finally {
a = 10;
b = 20;
return a+b;
}
}
}
I know however that the answer must be one of those three possibilities :
3
30
33
(PS: just in case someone is interested, here are the all the questions : http://se.inf.ethz.ch/courses/2014a_spring/JavaCSharp/exercise_sessions/ExerciseSession5.pdf)
The finally block is used for code that must always run, whether an error condition (exception) occurred or not.
The code in the finally block is run after the try block completes and, if a caught exception occurred, after the corresponding catch block completes. It should always run, even if an uncaught exception occurred in the try or catch block (Except if you got System.exit(0) in try block, because it will turn down the application before going to the finally block).
So your answer is 2. 30
Related
This question already has answers here:
Why is it possible to recover from a StackOverflowError?
(5 answers)
Closed 12 months ago.
I met the following problem in a Java exam, why following recursively calling a function can run forever even though StackOverflowError?
public class Solution {
static int i = 0;
public static void f(){
System.out.println(i++);
try {
f();
} catch (StackOverflowError e) {
System.out.println(e);
f();
}
}
public static void main(String[] args) {
f();
}
}
I cannot understand why JVM can still run when I've exhausted all call stack memory? Is there any reference, like JVM specification or JVM source code, can explain above phenomenon?
I'm neither java nor jvm expert, but I think adding a extra recursive depth output can show exactly what is going on with the call stack.
public class Solution {
static int i = 0;
public static void f(int depth) {
System.out.println(i++);
System.out.println(String.format("depth=%d", ++depth));
try {
f(depth);
} catch (StackOverflowError e) {
System.out.println(e);
f(depth);
}
}
public static void main(String[] args) {
f(1);
}
}
In my test, typical output is
...more
java.lang.StackOverflowError
161735
depth=3745
161736
depth=3746
161737
java.lang.StackOverflowError
161738
java.lang.StackOverflowError
161739
java.lang.StackOverflowError
161740
depth=3744
161741
depth=3745
...more
StackOverflowError is thrown because jvm is considering a size limit(1M by default?) of stack memory has reached, but the exception is caught, so the recursion is not stopped, it still tries to call, jvm throw away the recent 1 or 2 problematic calls, and then try continue, so the depth value goes around the same maximum value again and again.
I think this way the OP can understand why i is increasing without any problem. I've exhaust the call stack memory -- you haven't, you nearly exhaust, but jvm always cleared latest few calls to avoid exhaust.
This question already has answers here:
Mutithreading with System.out.format and System.out.println
(4 answers)
Closed 5 years ago.
I am trying to understand how to create a deadlock from https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html.
Instead of copy and pasting the sample code, I chose to write it by myself.
The last line in the link says "neither block will ever end because each thread is waiting for the other to exit bow" but never mentions about System.out.format.
I then wrote the below code and it never entered deadlock
public class DeadlockTest {
static class Resource {
public synchronized void test1(Resource r) {
System.out.print("test1");
r.test2();
}
public synchronized void test2() {
System.out.print("test2");
}
}
public static void main(String... a) {
final Resource r1 = new Resource();
final Resource r2 = new Resource();
new Thread(new Runnable() {
public void run() {
r1.test1(r2);
}
}).start();
new Thread(new Runnable() {
public void run() {
r2.test1(r1);
}
}).start();
}
}
So I tried to compare line by line and found that only the print statement is wrong. Instead of using System.out.format I used System.out.print. So the code never ran in to a dead lock situation. I then changed it to System.out.format and I was able to simulate a dead lock.
I even copied the example code from the link, changed the format statement to print/println and it was not entering deadlock.
Can anyone please explain how to exactly create a deadlock?
I took your code to test it. It indeed ran fine.
Only when I added a Thread.sleep(100) or the String.format in test1, it blocked. It seems as if your "work" method (print) is too fast. Before the second thread can cause the block by calling test1, the first thread is already finished with test2.
To stay in the tutorials example: Your threads did not in fact "bow at each other at the same time", but only "very quickly after one another". Make the bowing a little slower and you increase the chances of them bowing at the same time (still not guaranteed, e.g. if the system takes longer to schedule the second thread).
This question already has an answer here:
Why does the execution order between the printStackTrace() and the other methods appear to be nondeterministic?
(1 answer)
Closed 7 years ago.
I am trying to understand how the try-catch-finally execution flow works. There are a couple of solutions from Stack Overflow users regarding their execution flow.
One such example is:
try {
// ... some code: A
}
catch(...) {
// ... exception code: B
}
finally {
// finally code: C
}
Code A is going to be executed. If all goes well (i.e. no exceptions get thrown while A is executing), it is going to go to finally, so code C is going to be executed. If an exception is thrown while A is executed, then it will go to B and then finally to C.
However, I got different execution flows when I tried it:
try {
int a=4;
int b=0;
int c=a/b;
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally {
System.out.println("common");
}
I am getting two different outputs:
First output:
java.lang.ArithmeticException: / by zero
at substrings.main(substrings.java:15)
lication.AppMain.main(AppMain.java:140)
common
However, when I ran the same program for the second time:
Second output:
common
java.lang.ArithmeticException: / by zero
at substrings.main(substrings.java:15)
What should I conclude from this? Is it going to be random?
printStackTrace() outputs to standard error. System.out.println("common") outputs to standard output. Both of them are routed to the same console, but the order in which they appear on that console is not necessarily the order in which they were executed.
If you write to the same stream in both catch block and finally block (for example, try System.err.println("common")), you'll see that the catch block is always executed before the finally block when an exception is caught.
Exception's printstacktrace() method source code(defined in Throwable class)
public void printStackTrace() {
printStackTrace(System.err);
}
The formatting of output occurs because your are using standard output stream through System.out.printlnand exception occurs System.err stream
Try having a variable which will check exceptions and print in same error console if exception occurs :-
boolean isException = false;
try {
int a=4;
int b=0;
int c=a/b;
}
catch (Exception ex)
{
isException = true
ex.printStackTrace();
}
finally {
if(isException){
System.err.println("common");
}else{
System.out.println("common");
}
}
This question already has answers here:
try and Finally giving exception with no return statement , but there is no exception when return statement is written in method
(3 answers)
Closed 8 years ago.
Trying out a try catch finally use case -
public class Finallyy {
public static void main(String[] args) {
int result = method1();
System.out.println(result);
}
private static int method1() {
int a = 2;
try {
int b = 0;
a = a / a;
System.out.println("try");
return a;
} catch (Exception e) {
System.out.println("caught");
a = 5;
return a;
}
finally {
System.out.println("finally");
a = 10;
return a;
}
}
}
Output:
try
finally
10
If the code is modified to
finally {
System.out.println("finally");
a = 10;
//return a;
}
Output:
try
finally
1
Question - Is there some concept of stack where the 'return a' in try block is stored [if the example is altered, then it applies to try or catch block], and popped when control leaves the method1() only in the absence of a 'return' in finally block ?
Update: Solution concluded:
When the return statement is executed, the value to be returned is stored. When the finally block completes, that value is returned.
The finally block gets always executed as last. So the return in the finally block OVERWRITES the other returns in the try/catch blocks. It's a very bad practice to return or throw an exception from the finally block for this reason.
So to the original question - is it only in the absence of a 'return' in finally block ? NO. It doesn't matter.
Edit:
This question is asked on Apr 8 and is answered already. The question that is currently marked along with this as duplicate, is one asked at a later date [August 15]. Hence the new question is to be marked as duplicate, and not this one. However sharing the referenc eto a similar question is good.
A try block is executed before its finally block.
When the return statement is executed, the value to be returned is stored. When the finally block completes, that value is returned.
Note that a is not a value. a is a variable that stores a value. If you change a, you change a, you don't change the value that was stored for the return.
For the technical reason, we go to the Java Language Specification on the try-finally block
If execution of the try block completes abruptly for any other reason
R, then the finally block is executed, and then there is a choice:
If the finally block completes normally, then the try statement completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
A return statement completes abruptly, so if a try with a finally has a return and the finally also has a return, the finally's return supersedes the try's.
The finally block gets always executed as last. So the return in the finally block OVERWRITES the other returns in the try/catch blocks.
It's a very bad practice to return or throw an exception from the finally block for this reason.
Nothing to do with stacks: it's a matter of the fact that the finally block gets always executed as last block, so what is returned or thrown in the finally block erases and overwrites any previous exit value (returned object or exception thrown).
Try this:
try {
throw new NullPointerException();
}
finally {
return 0;
}
The return in the finally block will overwrite (swallow) the NullPointerException...
A try..catch..finally is actually compiled as a nested try..catch (of the exception you specify) within a try..catch (of "any"), and the "finally" block is cut & pasted by the compiler to the "end" of each code path. (I put "end" in quotes because I can't remember off the top of my head how it handles multiple exits from a "try" or "catch" block.) You can use the javap command (dis-assembler) to experiment on what byte code is generated by your version of Java to correspond to different try..catch..finally combinations.
There is this code:
public class Main {
public static void main(final String[] args) throws Exception {
System.out.print("1");
doAnything();
System.out.println("2");
}
private static void doAnything() {
try {
doAnything();
} catch (final Error e) {
System.out.print("y");
}
}
}
And there is the output:
1yyyyyyyy2
Why does it print "y" eight times and no more. How can Java call println() when StackOverflowError encountered?
Here you are catching Error and not Exception in which case your program would have crashed.
If you try this code (modified to add a static counter)
public class StackError {
static int i = 1;
public static void main(final String[] args) throws Exception {
System.out.print("1");
doAnything();
System.out.println("2");
}
private static void doAnything() {
try {
i++;
// System.out.println(i);
doAnything();
} catch (Error e) {
System.out.print("y"+i+"-");
}
}
}
Output
1y6869-2
So, it has got stackerror 6869 times(changes for different runs) and the last value is printed. If you just print the y as you did earlier then it might the case that the output is getting bufferred and not getting flushed as it is not a println.
Update
The System.out.println internally calls the PrintStream which is buffered. You don't loose any data from the buffer, it gets all written to the output( terminal in your case) after it fills up, or when you explicitly call flush on it.
Coming back to this scenario, it depends on the internal dynamics of how much the stack is filled up and how many print statements were able to get executed from the catch in doAnything() and those number of characters were written to the buffer. In the main back it finnally get's printed with the number 2.
javadoc reference to buffered streams
My bet is that by invoking print in the catch block you force another StackOverflowError that is caught by the outer block. Some of these calls will not have enough stack for actually writing the output stream.
The JLS says that:
Note that StackOverflowError, may be thrown synchronously by method
invocation as well as asynchronously due to native method execution
or Java virtual machine resource limitations.
The Java SE platform permits a small but bounded amount of execution
to occur before an asynchronous exception is thrown.
The delay noted above is permitted to allow optimized code to detect
and throw these exceptions at points where it is practical to handle
them while obeying the semantics of the Java programming language. A
simple implementation might poll for asynchronous exceptions at the
point of each control transfer instruction. Since a program has a
finite size, this provides a bound on the total delay in detecting an
asynchronous exception.
The first time the StackOverFlowError occurs, the call to the last doAnything() is cancelled and the control is returned to the catch block from the last doAnything().
However, because the stack is still practically full, the simple fact of calling System.out.print("y") will causes another StackOverflowError because of the need of pushing some value on the stack and then make a call to the function print().
Therefore, another StackOverflowError occurs again and the return is now returned on the catch{} block of the previous doAnything(); where another StackOverflowError will happens because the need of stack space required to do a single call to System.out.println("y") is greater than the amount of space liberated from returning a call from doAnything().
Only when there will be enough space on the stack to execute a call to System.out.print("y") that this process will stop and a catch block will successfully complete. We can see that by running the following piece of code:
public class Principal3b {
static int a = 0;
static int i = 0;
static int j = 0;
public static void main(String[] args) {
System.out.println("X");
doAnything();
System.out.println("Y");
System.out.println(i);
System.out.println(j);
}
private static void doAnything() {
a++;
int b = a;
try {
doAnything();
} catch (final Error e) {
i++;
System.out.println(a);
System.out.println(b);
j++;
}
}
}
Notice that a println(a) is used instead of a print(a); therefore a new line should be printed after each value of a if everything runs OK.
However, when I run it, I get the following result:
X
62066206620662066206620662066206
6190
Y
17
1
This means that there have been 17 attempts ro run the catch block. Of these catch block executions, 9 are unable to print anything before generating themselves a StackOverflowError; 7 are able to print the value of 6190 but are unable to print a newline after it before themselves rising an error again and finally, there is one that is able to both print the value of 6190 and the newline after it; therefore finally permitting its catch block to complete without any new StackOverflowError and return gracefully up the calls stack.
As we are dealing with StackOverflowError, these numbers are only an example and will vary greatly not only between machines but also between executions and the simple fact of adding or removing any kind of instructions should also change these values. However, the pattern seen here should remains the same.
One thing is clear that System.out.print("y"); in catch creates this puzzle. If we change the code as
static int n;
public static void main(final String[] args) throws Exception {
System.out.println("1");
doAnything();
System.out.println(n);
}
private static void doAnything() {
try {
doAnything();
} catch (Error e) {
n++;
}
}
it prints
1
1
Well the no. of times the stack overflow error is hit is undefined. However, the JVM allows you to recover from StackOverflowError error and continue execution of the system normally.
It is proved by the following code:
public class Really {
public static void main(final String[] args) throws Exception {
System.out.print("1");
doAnything();
System.out.println("2");
}
private static void doAnything() {
try {
throw new StackOverflowError();
//doAnything();
}
catch(final Error e){
System.out.print("y");
}
}
}
Note however, as #Javier said, the StackOverflowError is thrown by the JVM synchronously or asynchronously(which means it can be thrown by another thread, possibly a native thread) which is why it is not possible to get the stack trace of the error. The no. of times the thread(s) hit the catch() block is undefined.
In addition, Objects of type Error are not Exceptions objects they represent exceptional conditions.
Errors represent unusual situations that are not caused by program errors,
usually does not normally happen during program execution, such as JVM running out of memory.
Although they share a common superclass Throwable, meaning both can be thrown, it can
be placed in a catch but generally not supposed to be caught, as they represent
rare, difficult-to-handle exceptional conditions.
Stack overflow.
You are only printing on exception,in the meantime the program recurses into overflow.
At which point this occurs depends on individual systems, memory, etc.
What is the purpose of the program?