Setting outer variable from anonymous inner class

后端 未结 9 842
臣服心动
臣服心动 2020-11-28 07:03

Is there any way to access caller-scoped variables from an anonymous inner class in Java?

Here\'s the sample code to understand what I need:

public L         


        
9条回答
  •  自闭症患者
    2020-11-28 08:09

    The standard solution to this is to return a value. See, for instance, ye olde java.security.AccessController.doPrivileged.

    So the code would look something like this:

    public Long getNumber(
        final String type, final String refNumber, final Long year
    ) throws ServiceException {
        try {
            Session session = PersistenceHelper.getSession();
            return session.doWork(new Work() {
                public Long execute(Connection conn) throws SQLException {
                    CallableStatement st = conn.prepareCall("{ CALL PACKAGE.procedure(?, ?, ?, ?) }");
                    try {
                        st.setString(1, type);
                        st.setString(2, refNumber);
                        st.setLong(3, year);
                        st.registerOutParameter(4, OracleTypes.NUMBER);
                        st.execute();
                        return st.getLong(4);
                    } finally {
                        st.close();
                    }
                }
            });
        } catch (Exception e) {
            throw ServiceException(e);
        }
    }
    

    (Also fixed the potential resource leak, and returning null for any error.)

    Update: So apparently Work is from a third-party library and can't be altered. So I suggest not using it, at least isolate your application from so that you are not using it directly. Something like:

    public interface WithConnection {
        T execute(Connection connnection) throws SQLException;
    }
    public class SessionWrapper {
        private final Session session;
        public SessionWrapper(Session session) {
            session = nonnull(session);
        }
        public  T withConnection(final WithConnection task) throws Service Exception {
            nonnull(task);
            return new Work() {
                T result;
                {
                    session.doWork(this);
                }
                public void execute(Connection connection) throws SQLException {
                    result = task.execute(connection);
                }
            }.result;
        }
    }
    

提交回复
热议问题