Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access a try-with-resource variable outside the block?

Tags:

java

Why can't I assign a try-with-resource variable outside of the try block?

The following statement is invalid:

Connection con = null;
try (con = DatabaseService.getConnection()) { //this is invalid. why?
     con.execute(...);
} catch (Exception e) {
    con.rollback();
}

How can I get access to the con variable inside the catch block?

like image 669
membersound Avatar asked May 22 '18 15:05

membersound


People also ask

How do you access variables in try block?

Variables in try block So, if you declare a variable in try block, (for that matter in any block) it will be local to that particular block, the life time of the variable expires after the execution of the block. Therefore, you cannot access any variable declared in a block, outside it.

Can we use try-with-resources without catch and finally?

Yes, It is possible to have a try block without a catch block by using a final block. As we know, a final block will always execute even there is an exception occurred in a try block, except System. exit() it will execute always.

How do you catch exceptions in try-with-resources?

You can add a catch block to a try-with-resources block just like you can to a standard try block. If an exception is thrown from within the try block of a try-with-resources block, the catch block will catch it, just like it would when used with a standard try construct.

How do you use try-with-resources?

In Java, the try-with-resources statement is a try statement that declares one or more resources. The resource is as an object that must be closed after finishing the program. The try-with-resources statement ensures that each resource is closed at the end of the statement execution.


5 Answers

This is only with Java version 8. It has improved Since Java 9.

With Java 9 the Try-With-Resources has been improved by introducing a new syntax:

public void loadDataFromDB() throws SQLException {
    Connection dbCon = DriverManager.getConnection("url", "user", "password");
    try (dbCon; ResultSet rs = dbCon.createStatement().executeQuery("select * from emp")) {
        while (rs.next()) {
            System.out.println("In method loadDataFromDB()" + rs.getString(1));
        }
    } catch (SQLException e) {
        System.out.println("Exception occured while reading data from DB " + e.getMessage());
    }
}

The same when compiled with Java 8 or lesser version will result in a compilation error.

In Java 9 you can use the variables in the scope of try and catch blocks.

like image 152
Eby Jacob Avatar answered Oct 23 '22 02:10

Eby Jacob


I'd design it like this:

try (Connection con = DatabaseService.getConnection()) {
    try {
        con.execute(...);
    } catch (Exception e) {
        con.rollback();
    }
}
like image 26
Luiggi Mendoza Avatar answered Oct 23 '22 02:10

Luiggi Mendoza


Since try-with-resources calls close() on a AutoCloseable class, you could go back to manually closing the connection:

Connection con = DatabaseService.getConnection();
try {
    con.execute(...);
} catch (Exception e) {
    con.rollback();
} finally {
    con.close();
}
like image 44
TomVW Avatar answered Oct 23 '22 02:10

TomVW


My answer is based on answer from @Luiggi Mendoza:

public void doWithConnection() throws SQLException {
    try (Connection con = DatabaseService.getConnection()) {
        execute(con);
    }
}

private void execute(Connection con) throws SQLException {
    try {
        // TODO do smth. here
    } catch(Exception e) {
        con.rollback();
    }
}
like image 41
oleg.cherednik Avatar answered Oct 23 '22 02:10

oleg.cherednik


In fact, since Java 9 you can use try-with-resources with final or effective final variables. So you can initialize the variable outside the try block, and just indicate that you want to use it in the try-with-resources block. This way the variable is available in the scope of the catch block.

Connection con = DatabaseService.getConnection();
try (con) {
     con.execute(...);
} catch (Exception e) {
    con.rollback();
}

Note: Even though the variable will be available in the catch method, the call to the close() method will happen before it enters the catch or finally blocks. So in this case it won't be useful to call a rollback() in a transaction, but it is to gather additional information from the object state.

like image 21
Edison Klafke Fillus Avatar answered Oct 23 '22 01:10

Edison Klafke Fillus