TC1*_*TC1 52 java anonymous-class
有没有办法从Java中的匿名内部类访问调用者范围的变量?
以下是了解我需要的示例代码:
public Long getNumber(final String type, final String refNumber, final Long year) throws ServiceException {
Long result = null;
try {
Session session = PersistenceHelper.getSession();
session.doWork(new Work() {
public void execute(Connection conn) throws SQLException {
CallableStatement st = conn.prepareCall("{ CALL PACKAGE.procedure(?, ?, ?, ?) }");
st.setString(1, type);
st.setString(2, refNumber);
st.setLong(3, year);
st.registerOutParameter(4, OracleTypes.NUMBER);
st.execute();
result = st.getLong(4) ;
}
});
} catch (Exception e) {
log.error(e);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
代码位于DAO服务类中.显然它不会编译,因为它要求result是final,如果是 - 它不会编译,因为我尝试修改最终的var.我被JDK5绑定了.除了doWork()完全放弃之外,有没有办法从内部设置结果值doWork()?
Lou*_*nco 62
Java不知道doWork将是同步的,并且结果所在的堆栈帧仍然存在.你需要改变堆栈中没有的东西.
我认为这会奏效
final Long[] result = new Long[1];
Run Code Online (Sandbox Code Playgroud)
然后
result[0] = st.getLong(4);
Run Code Online (Sandbox Code Playgroud)
在execute().最后,你需要return result[0];
小智 15
这种情况在Java中出现很多,处理它的最简单方法是使用简单的值容器类.它与阵列方法的类型相同,但IMO更清晰.
public class ValContainer<T> {
private T val;
public ValContainer() {
}
public ValContainer(T v) {
this.val = v;
}
public T getVal() {
return val;
}
public void setVal(T val) {
this.val = val;
}
}
Run Code Online (Sandbox Code Playgroud)
如果包含的类是MyClass - >
MyClass.this.variable = value;
Run Code Online (Sandbox Code Playgroud)
不记得这是否适用于私有变量(我认为它会起作用).
仅适用于类的属性(类变量).不适用于方法局部变量.在JSE 7中,可能会有闭包来做这种事情.
龙是不变的.如果使用可变类,持有long值,则可以更改该值.例如:
public class Main {
public static void main( String[] args ) throws Exception {
Main a = new Main();
System.out.println( a.getNumber() );
}
public void doWork( Work work ) {
work.doWork();
}
public Long getNumber() {
final LongHolder result = new LongHolder();
doWork( new Work() {
public void doWork() {
result.value = 1L;
}
} );
return result.value;
}
private static class LongHolder {
public Long value;
}
private static abstract class Work {
public abstract void doWork();
}
}
Run Code Online (Sandbox Code Playgroud)
最简单(最简单)的方法是使用AtomicLongJava 1.5以来的可用方法
public Long getNumber(final String type, final String refNumber, final Long year) throws ServiceException {
final AtomicLong result = new AtomicLong;
try {
Session session = PersistenceHelper.getSession();
session.doWork(new Work() {
public void execute(Connection conn) throws SQLException {
//...
result.set(4);
//...
}
});
} catch (Exception e) {
log.error(e);
}
return result.get;
}
Run Code Online (Sandbox Code Playgroud)
在还有其他AtomicXXX变体可java.util.concurrent.atomic包:AtomicInteger,AtomicBoolean,AtomicReference<V> (for your POJOs)等
| 归档时间: |
|
| 查看次数: |
44086 次 |
| 最近记录: |