When the below method is called it's printing output as 6 but I am expecting output as 5 as I have re-assigned n = 5 in the finally block.
Can anybody please help me with this?
public static int p() {
int n = 0;
try {
n = 6 ;
return n;
} catch (Exception e) {
return n;
} finally {
n = 5;
}
}
This can easily be answered by understanding the order of execution of your code. In your scenario you will always be returning the value of n before you hit the final block, in your code you will always be returning the value of 6. You will never return 5 (Final Block) or 0 (Catch Block).
So why would you never get 0?
You would never get 0 because the code within the try part of your try-catch-final statement will never in a million years throw any exception the way it has been written, so the catch statement is redundant.
So why would you never get 5?
You would never get 5 because the order of execution is return statement in the try block is executed first and then the final block runs. A try-final statement is the only statement I can think of (Happy to be proven wrong in comments) that any code is executed after a return statement is executed.
There is no reason why in your scenario you would have that final block unless for whatever reason you didn't trust the Garbage Collector was doing it's job, in which case you would nullify the n property here and that's it.
Your code could easily be re-written as the below because 6 is the only value your code will ever return.
public static int p() {
return 6;
}
As mentioned by luk2302 you are already return the value as 6. If you want to return the value as 5 then change your method as shown below.
public static int p() {
int n = 0;
try {
n = 6;
} catch (Exception e) {
return n;
} finally {
n = 5;
}
return n;
}
Question is very interesting, i even surprised why it is happening like that. When i checked about finally block i got the definition like below
"Java finally block is a block used to execute important code such as closing the connection, etc. Java finally block is always executed whether an exception is handled or not. Therefore, it contains all the necessary statements that need to be printed regardless of the exception occurs or not."
But i have compiled your program and saw how the compiled class looks like. It gives the answer
Original Java class
public class Finally {
public static int p() {
int n = 0;
try {
n = 6 ;
return n;
} catch (Exception e) {
return n;
} finally {
n = 5;
}
}
public static void main(String[] args) {
int n = p();
System.out.println("value of n " + n);
}
}
Compiled class
public class Finally {
public Finally() {
}
public static int p() {
byte n = 0;
byte var2;
try {
n = 6;
byte var1 = n;
return var1;
} catch (Exception var6) {
var2 = n;
} finally {
boolean var8 = true;
}
return var2;
}
public static void main(String[] args) {
int n = p();
System.out.println("value of n " + n);
}
}
As you can see how return statements translated due to that we don't see the value which is assigned in finally block instead we see value which is assigned in the try block.
Hope that clarify your answer.
Related
This question already has answers here:
Thread safety in java multithreading
(3 answers)
Difference between volatile and synchronized in Java
(4 answers)
Closed 1 year ago.
My problem is that the code should increment a 1000 times and then output it. But sometimes a isn't 1000 at the end.
public class Counter extends Thread {
private static Integer a = 0;
public void run() {
for (int i = 0; i < 100; i++) {
a++;
}
}
public static void main(String[] args) {
Counter[] ca = new Counter[10];
for (int i = 0; i < 10; i++) {
ca[i] = new Counter();
ca[i].start();
}
for (Counter c : ca) {
try {
c.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(a);
}
This code is the original code that is obviously not going to work because I have multiple Threads accessing the variable a. I've tried putting a synchronized(this) around a++; and marking a as volatile but I still sometimes get a false Result. The only way I've found to make it work reliably it to put join() into the for loop, but that kind of defeats the point of using Threads in the first place.
Any help is appreciated.
There are several problems in the code you posted, and all them a reported in the comments to your qestion.
I try to show the major ones:
Variable a is Integer which is immutable, this means that a++ really means create a new Ineger instance containing the old value plus 1.
the variable a is updated by multiple threads concurrenlty without synchonizazion, this means that the operation a=a+1 canbe split in read a, increment a; if two or more thread read a at the same time the the increment by one the same value
Here is a modified version that uses a Lock to synchronize access to the resource. The main scope of this code is to show that the access to a must be synchronixed between thread; in order to get a "clean design" you must refactor/change a lot of other things.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SyncProblem {
private static int a=0;
private static class IncThread extends Thread {
private Lock lock;
public IncThread(Lock lock) {
this.lock=lock;
}
public void run() {
lock.lock();
try {
for (int i = 0; i < 100; i++) {
a++;
}
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
Lock lock= new ReentrantLock();
IncThread[] ca = new IncThread[10];
for (int i = 0; i < 10; i++) {
ca[i] = new IncThread(lock);
ca[i].start();
}
for (IncThread c : ca) {
try {
c.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(a);
}
}
I use this code to test try catch finally:
public class My{
public static void main(String[] args) {
System.out.println(fun1());
System.out.println(fun2());
}
public static int fun1() {
int a = 1;
try {
System.out.println(a / 0);
a = 2;
} catch (ArithmeticException e) {
a = 3;
return a;
} finally {
a = 4;
}
return a;
}
public static int fun2() {
int a = 1;
try {
System.out.println(a / 0);
a = 2;
} catch (ArithmeticException e) {
a = 3;
return a;
} finally {
a = 4;
return a;
}
}
}
output:
3
4
I know that finally will always run. I think the result of the two functions should be 4, but actually fun1() is 3 and the fun2() is 4. Why?
This question is closely related, although it returns literals but not variables: Multiple returns: Which one sets the final return value?
In fun1 the return value is set via return a in the catch-block. At that line the value of a is copied into the return value. Changing a later does not change the return value.
In fun2 you have an explicit return in the finally block, so the return value in the finally block is what is returned.
Please read carefully through the answers in the question above for why you should not write code like that.
Another related question is this one: Returning from a finally block in Java
In simple words when a function returns something it returns from the last executed return statement. in fun2() first return value is 3 which gets overridden by finally block's return value i.e 4. Whereas in fun1() method return is set to 3 from catch block and since the last line of func1() never gets executed hence 3 is returned.
I'm preparing myself for fall exam in Object Oriented Programming and one type of tasks we are given is providing output from code which usually consists of some Exception handling problems.
Now my question is when does try-with-resources close it's resource because my output is strictly dependent on output from class that implements AutoCloseable.
In provided code, what I don't understand why "close 1" output comes before "close 40", or why is object A(40) closed at the end of this block. Is it because A(50) is same type as A(40)?
My main question when does the AutoCloseable close the given resource, like in example m1 when i=1:
1) A(1) is created
1b) Try block is executed
2) A(1) is closed
3) ArrayIndexOutOfBoundsException is handled?
public class Main {
public static void main(String[] args) {
int[] arr = new int[] { 15, 10 };
for(int i=1; i>=-1; i--){
try(A a40 = new A(40)) {
m1(arr, i);
A a50 = new A(50);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("array exc");
}
catch(Exception e) {
System.out.println("main exc");
break;
}
finally {
System.out.println("main finally");
}
}
System.out.println("main done");
}
private static void m1(int[] arr, int i) throws Exception {
try(A a1 = new A(i)) {
m2(arr[i] + arr[i+1], i);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("m1 exc");
}
System.out.println("m1 done");
}
private static int m2(int x, int y) {
int r = 0;
try{
A a2 = new A(x+y);
r = x / y;
}
finally {
System.out.println("m2 finally");
}
System.out.println("m2 done");
return r;
}
}
And class A which implements AutoCloseable:
public class A implements AutoCloseable {
private int x;
public A(int x){
this.x = x;
System.out.println("A " + x);
}
#Override
public void close() throws Exception {
System.out.println("close " + x);
}
}
Here is output of provided code:
A 40
A 1
close 1
m1 exc
m1 done
A 50
close 40
main finally
A 40
A 0
A 25
m2 finally
close 0
close 40
main exc
main finally
main done
The specification is pretty clear on this.
14.20.3. try-with-resources
A try-with-resources statement is parameterized with local variables (known as resources) that are initialized before execution
of the try block and closed automatically, in the reverse order from
which they were initialized, after execution of the try block.
Your example is a bit convoluted. Try to simplify it. There are two scenarios you are interested in: an exception thrown in the try block, an exception isn't thrown in the try block. You debugging messages is informative, so you will be able to track the flow easily.
You may want to look into decompiled .classes to see what actually was generated.
I have an action listener that calls some methods and one of those methods counts the number of times that a loop inside of another method is run. The problem I am having is that the counter just adds to itself (I understand why I just don't know how to fix it) rather than resetting back to 0.
Here is my action listener code.
public double computeIterative(double n) throws InvalidInput {
int a=1, b=2;
int result = 0;
if (n>=0) {
if(n==0)return 0;
if(n==1)return 1;
if(n==2)return 2;
for(int i = 3; i <= n; i++) {
result = a+(2*b);
a=b;
b = result;
this.getEfficiency();
}
} else{
throw new InvalidInput();
}
return result;
}
ActionListener that calls methods and sets text:
public void actionPerformed(ActionEvent e) {
int n = Integer.parseInt(nField.getText());
//Try Catch for Iterate Radio Button
if (iterateBtn.isSelected()){
try {
double result = sequence.computeIterative(n);
int efficiency = sequence.getEfficiency();
rField.setText(Double.toString(result));
eField.setText(Integer.toString(efficiency));
}
catch (InvalidInput ex) {
}
}
The getEfficiency method counts how many times the loop inside computeIterative method is run and then sets it to a textField.
Here is my getEfficiency method:
public int getEfficiency() {
efficiency++;
return efficiency;
}
Now obviously this will just keep adding onto itself, and I am sure that I am looking way too hard for a solution but I just cant figure it out.
Basically, after the try, catch, I need to set efficiency to 0 so that the next time the computeIterative(n) method is called, I get a proper reading.
You could simply add a method resetEfficiency():
public int resetEfficiency() {
efficiency = 0;
}
And then call it at the beginning of computeIterative():
public double computeIterative(double n) throws InvalidInput {
this.resetEfficiency();
//rest of code goes here
//....
}
(Of course I'm assuming this is not multi-threaded or anything).
public double computeIterative(double n) throws InvalidInput {
int a=1, b=2;
int result = 0;
this.resetEfficiencyCounter(); //Call Reset if Number Got Invalid.
if (n>=0) {
if(n==0)return 0;
if(n==1)return 1;
if(n==2)return 2;
for(int i = 3; i <= n; i++) {
result = a+(2*b);
a=b;
b = result;
this.getEfficiency();
}
} else{
throw new InvalidInput();
}
return result;
}
add new Function Named resetEfficiencyCounter().
private void resetEfficiencyCounter(){
this.efficiency = 0;
}
I am writing a very simple program in Java that tries to divide 10 by a user-entered number and catches a DivideByZeroException. Here is the code:
public class EnhancedCatchExceptions6 {
public static void main(String[] args) {
System.out.println();
for (int i = 0 ; i < i; i++) {
try {
int b = Input.getInt("Enter an integer to divide by:");
divide(10, b);
break;
} catch (DivideByZeroException e) {
System.out.println("Error: Divided by zero. Try again.\n");
}
}
}
public static int divide(int x, int y) throws DivideByZeroException {
System.out.println();
int result = 0;
try {result = x/y;}
catch (ArithmeticException e) {throw new DivideByZeroException(y);}
return result;
}
}
For some reason is returns an error: cannot find symbol for every 'DivideByZeroException.' If I change DivideByZeroException to Exception it does not return that error. The same error appears when I was writing other programs with other exceptions.
I don't understand why this error is returned and I would appreciate any help. Thanks!
Most likely this is happening because you forget to import your DivideByZeroException. Change the first lines of your class adding:
import your.package.name.DivideByZeroException;
and you should be fine. Do not forget to use real package name of yours, of course.
The other guess - if you want a class that represents an exception and comes with JDK, not your own, consider replacing DivideByZeroException with ArithmeticException.