Yakhoob
Yakhoob

Reputation: 569

Use non-final variable inside inner method using Java

Im using Jdbctemplate and trying to set a boolean value inside the mapRow method. But it doesnt allow, It says

Cannot refer to a non-final variable isEveryTransactionNotClosed inside an inner class defined in a different method

Here is my code

public boolean isEveryTransactionNotClosed (String txIds) throws QiibException {
    String sql = "<Query> ";
    logger.info("isEveryTransactionNotClosed SQL :"+sql);
    boolean isEveryTransactionNotClosed = true;
    try {
        isEveryDealNotClosed =  getJdbcTemplate().queryForObject(sql, new Object[] {dealIds}, 
                new RowMapper<Boolean>()  {
                public Boolean mapRow(ResultSet rs, int rowNum) throws SQLException {
                    if (!rs.next()) {
                        isEveryTransactionNotClosed = false;    -->                         
                    }
                }
        });
    } catch(EmptyResultDataAccessException e) {
        logger.error("Empty result data - isEveryTransactionNotClosed ");   
    }
   return isEveryTransactionNotClosed ;
}

How can I use isEveryTransactionNotClosed inside class?

Upvotes: 0

Views: 389

Answers (3)

Stultuske
Stultuske

Reputation: 9427

There are some issues with your code:

    public boolean isEveryTransactionNotClosed (String txIds) throws QiibException {
        String sql = "<Query> ";
        logger.info("isEveryTransactionNotClosed SQL :"+sql);
        try {
            final boolean isEveryDealNotClosed =  getJdbcTemplate().queryForObject(sql, new Object[] {dealIds}, 
                    new RowMapper<Boolean>()  {
                    public Boolean mapRow(ResultSet rs, int rowNum) throws SQLException {
                        if (!rs.next()) {
                            isEveryTransactionNotClosed = false;    -->                         
                        }
                    }
            });
        } catch(EmptyResultDataAccessException e) {
            logger.error("Empty result data - isEveryTransactionNotClosed ");   
        }
       return isEveryTransactionNotClosed ;
    }

would solve the issue you have now, which would give two new issues:

 1. You would try to re-assign a final variable
 2. Your method has a return value Boolean, but doesn't return anything.

Change your code to:

public boolean isEveryTransactionNotClosed (String txIds) throws QiibException {
    String sql = "<Query> ";
    logger.info("isEveryTransactionNotClosed SQL :"+sql);
    boolean isEveryDealNotClosed = true;
    try {
        isEveryDealNotClosed =  getJdbcTemplate().queryForObject(sql, new Object[] {dealIds}, 
                new RowMapper<Boolean>()  {
                public Boolean mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return rs.next();
                }
        });
    } catch(EmptyResultDataAccessException e) {
        logger.error("Empty result data - isEveryTransactionNotClosed ");   
    }
   return isEveryDealNotClosed;
}

Upvotes: 1

AxelH
AxelH

Reputation: 14572

The solution of Stultuske is correct. But it is not explaining the reason of the error.

The short answer is that you can't use a non-final local variable in an inner-class. It can be effectivly final (so it doesn't really need the keyword).

From the JLS - 8.1.3. Inner Classes and Enclosing Instances

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final.

Explaining your problem.

It is not final and definitly not effectivly final since your inner class alter the local variable.

Another solutions :

  • Inner class are allowed to access and modify member variables,
  • Use wrapper to create the final instance olding your value

Upvotes: 1

Alex
Alex

Reputation: 803

You may use AtomicBoolean in place of boolean if you need a final changeable boolean. See below for the changes on your code.

However, there is some other errors in your code, as stated by others. You may need to change it as well in order to make it work.

public boolean isEveryTransactionNotClosed (String txIds) throws QiibException {
    String sql = "<Query> ";
    logger.info("isEveryTransactionNotClosed SQL :"+sql);
    // changed line
    final AtomicBoolean isEveryTransactionNotClosed = new AtomicBoolean(true);
    try {
        isEveryDealNotClosed =  getJdbcTemplate().queryForObject(sql, new Object[] {dealIds}, 
                new RowMapper<Boolean>()  {
                public Boolean mapRow(ResultSet rs, int rowNum) throws SQLException {
                    if (!rs.next()) {
                        // changed line
                        isEveryTransactionNotClosed.set(false);                         
                    }
                }
        });
    } catch(EmptyResultDataAccessException e) {
        logger.error("Empty result data - isEveryTransactionNotClosed ");   
    }
   return isEveryTransactionNotClosed.get();
}

Upvotes: 1

Related Questions