When does try-with-resources close the resource? - java

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.

Related

Finally block excecution

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.

Threads changing the same Variable wont synchronize [duplicate]

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);
}
}

Exceptions and Output in Java [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I would like to be able to tell for sure when the compiler throws an exception with no output and when it's going to execute a few lines of code followed by an exception.
To further illustrate my point, consider the following code:
public class OverAndOver {
static String s = "";
public static void main(String[] args) {
try {
s += "1";
throw new Exception();
} catch (Exception e) { s += "2";
} finally { s += "3"; doStuff(); s += "4";
}
System.out.println(s);
}
static void doStuff() { int x = 0; int y = 7/x; }
}
A quick glance at the doStuff() method and you know the compiler is going to throw a Divide-by-zero exception.
Now, here's my question though (and the source of my confusion): Why didn't the compiler displayed "123" followed by the exception? And most importantly, how can I be able to tell for sure when the compiler is going to execute a few lines of code before throwing an exception and when it's going to throw an exception right away with no output?
Why didn't the compiler displayed "123" followed by the exception?
First of all, the compiler doesn't execute the code, so it will never display those values.
If you wonder why your app didn't display the text before the exception, the answer is that you didn't print it: you just append it to a string, and you print the string after the finally block.
The finally block throws an exception and your print statement will never be reached.
Try to print the text directly:
public class OverAndOver {
public static void main(String[] args) {
try {
System.out.println("1");
throw new Exception();
} catch (Exception e) {
System.out.println("2");
} finally {
System.out.println("3");
doStuff();
System.out.println("4");
}
}
static void doStuff() {
int x = 0;
int y = 7 / x;
}
}
The output will be:
1
2
3
Exception in thread "main"
java.lang.ArithmeticException: / by zero
at com.jedisoftware.lf_delivery_tracking.OverAndOver.doStuff(App.java:74)
at com.jedisoftware.lf_delivery_tracking.OverAndOver.main(App.java:67)
Why didn't the compiler displayed "123" followed by the exception?
Because System.out.println(s); instruction is never executed.. Exception is raised in the doStuff(); method and the execution of main method is interrupted.
If you want to display 123 before the exception you should put the System.out.println(s); instruction before the doStuff() method as follows:
public class OverAndOver {
static String s = "";
public static void main(String[] args) {
try {
s += "1";
throw new Exception();
} catch (Exception e) { s += "2";
} finally { s += "3"; System.out.println(s); doStuff(); s += "4";
}
}
static void doStuff() { int x = 0; int y = 7/x; }
}
You call doStuff() which may throw an unchecked exception outside of a try block. If you want to print both the exception and the string you must wrap the doStuff() call in a try-catch construct.
public class OverAndOver {
static String s = "";
public static void main(String[] args) {
try {
s += "1";
throw new Exception();
} catch (Exception e) { s += "2";
} finally {
try{
s += "3"; doStuff(); s += "4";
}catch(ArithmeticException e){
e.printStackTrace();
}
}
System.out.println(s);
}
static void doStuff() { int x = 0; int y = 7/x; }
}

Error: cannot find symbol for Exceptions in Java

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.

exception handling and finally block in java

public class Confusion {
Confusion(int i) {
int j = 5;
int[] a = new int[2];
try {
a[0] = 4;
if (i <= 0) {
int k = j / i;
} else {
System.out.println(j / i);
}
} catch (ArithmeticException sa) {
System.out.println("Wrong value" + sa);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("out of range massage in Class");
} finally {
System.out.println("Executing finally block in code");
}
}
void k() {
int[] a = new int[2];
{
try {
a[4] = 4;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("out of range");
}
}
}
}
public class Nested {
public static void main(String[] args) {
Confusion c = new Confusion(2);
Confusion c1 = new Confusion(0);
c1.k();
c.k();
}
}
Output:
-2
Executing finally block in code
Wrong valuejava.lang.ArithmeticException: / by zero
Executing finally block in code
out of range
out of range
Whenever i am executing the finally{} block written in the code below it is getting executed twice. Don't know why this is happening. I want to run the finally block only once.
Is there any way to throw multiple exception in single method?
It because you have two Confusion objects. Therefore, the constructor will be executed twice.
confusion c=new confusion(2);
confusion c1=new confusion(0);
confusion c=new confusion(2);
confusion c1=new confusion(0);
thats why u are getting 2 outputs from finally.
This is because you are creating two objects c1 and c
The finally block always executes when the try block exits.
http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
So regardless of any exception it will execute finally block. As you create two objects, it will call the constructor twice and will also execute finally twice.
You are calling the code in the try twice.
confusion c=new confusion(2);
confusion c1=new confusion(0);
This means that as the finally happens every time the try is called, it'll print...
Executing finally block in code
If you called it again,
confusion c1=new confusion(3);
It'd print out the contents of the finally a third time.
You are creating two objects using following code. Thats why the finally block is executed two times.
confusion c=new confusion(2);
confusion c1=new confusion(0);
Try this one please
public static void main(String[] args){
confusion c=new confusion(2);
confusion c1=new confusion(0);
confusion c1=new confusion(10);
confusion c1=new confusion(5);
}
Now finally block called 4 times.
Constructor in Java is block of code which is executed at the time of Object creation.
Please read constructor reference http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
Because you are creating two Confusion objects. Therefore, the finally block will be executed twice.
confusion c=new confusion(2);
confusion c1=new confusion(0);
If you want to execute finally only once.Try this code
public class Confusion {
Confusion(int i) {
int j = 5;
int[] a = new int[2];
a[0] = 4;
if (i <= 0) {
int k = j / i;
} else {
System.out.println(j / i);
}
}
void k() {
int[] a = new int[2];
a[4] = 4;
}
}
public class Nested {
public static void main(String[] args) {
try{
Confusion c = new Confusion(2);
Confusion c1 = new Confusion(0);
c1.k();
c.k();
}catch (ArithmeticException sa) {
System.out.println("Wrong value" + sa);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("out of range massage in Class");
} finally {
System.out.println("Executing finally block in code");
}
}
}

Categories