Using finally with return statement or not I was wondering if it is the proper way to always put the return statement of a function with a try-catch clause in the finally clause.

I have for example this function which returns the version of an sql server:

public String getVersion() {
        String version = new String();
        final String query = "Select VERSION()";
        Connection con = null;
        Statement stmt = null;

        try {
            Helper.println("Getting driver...");
            Class.forName(_driver);

            Helper.println("Connecting to database...");
            con = DriverManager.getConnection(_url, _user._username, _user._password);
            stmt = con.createStatement();

            Helper.println("Executing query...");
            ResultSet rs = stmt.executeQuery(query);
            rs.next();
            version = rs.getString(1);
        } catch (SQLException se) {
            Helper.printErrln("SQL Error: " + se.getErrorCode() + ' ' + se.getMessage());
        } catch (ClassNotFoundException e) {
            Helper.printErrln("Driver Error: " + e.getMessage());
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (SQLException se) {
            }
            try {
                if (con != null) {
                    con.close();
                }
            } catch (SQLException se) {
            }  
            return version;
        }
    }


I return the version variable always in the finally clause in situations like these and it particularly convenient when I need to return a list because if something went wrong then I will just be left with an empty list which I prefer. For example: 

public List&lt;String&gt; getDatabases() {
        List&lt;String&gt; databases = new ArrayList&lt;&gt;();
        Connection con = null;
        Statement stmt = null;

        try {
            Helper.println("Getting driver...");
            Class.forName(_driver);

            Helper.println("Connecting to database...");
            con = DriverManager.getConnection(_url, _user._username, _user._password);
            stmt = con.createStatement();

            Helper.println("Finding Databases...");
            ResultSet rs = con.getMetaData().getCatalogs();

            while (rs.next()) {
                databases.add(rs.getString("TABLE_CAT"));
            }
        } catch (SQLException se) {
            Helper.printErrln("SQL Error: " + se.getErrorCode() + " " + se.getMessage());
        } catch (ClassNotFoundException e) {
            Helper.printErrln("Driver Error: " + e.getMessage());
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (SQLException se) {
            }// do nothing
            try {
                if (con != null) {
                    con.close();
                }
            } catch (SQLException se) {
            }      
            return databases;
        }
    }


So first of all my question is: Is what I am doing proper or can it cause problems that I have not anticipated? Also what if I wanted to encapsulate the function and have it trow the exception to the parent class for handling, how would the return be handled then?
Return statement in the finally block is almost always a very bad idea.....

The sematics of the finally block are complicated, but, if there is a return statement the try block, or in a catch block, then those will be called, and then the finally block will run, and it will change the return value.

IDE's, and the compiler, will complain about this:



Code like the following, will return 2 .... always:

private static int doSomething() {
    try {
        .... something here....
        return 0;
    } catch (Exception e) {
        return 1;
    } finally {
        return 2;
    }

}


The point is that it is very bad practice to have returns in the finally block. Don't.....

EDIT: Update to include a better solution.... Use Java try-with-resources (since Java7).

private static final String VERSION_QUERY = "Select VERSION()";
private static final String VERSION_NOT_FOUND = "";

public String getVersion() {

    try {
        Helper.println("Getting driver...");
        Class.forName(_driver);
    } catch (ClassNotFoundException e) {
        Helper.printErrln("Driver Error: " + e.getMessage());
        return VERSION_NOT_FOUND;
    }


    Helper.println("Connecting to database...");
    try (Connection con = DriverManager.getConnection(_url, _user._username, _user._password);
         Statement stmt = con.createStatement();) {

        Helper.println("Executing query...");
        try (ResultSet rs = stmt.executeQuery(VERSION_QUERY);) {
            rs.next();
            return rs.getString(1);
        }
    } catch (SQLException se) {
        Helper.printErrln("SQL Error: " + se.getErrorCode() + ' ' + se.getMessage());
        return VERSION_NOT_FOUND;
    }
}