用于解决Java闭包的最终限制的模式

时间:2012-06-07 18:45:29

标签: java coding-style closures

我正在尝试编写一段非常简单的代码,但无法找到一个优雅的解决方案:

int count = 0;
jdbcTemplate.query(readQuery, new RowCallbackHandler() {
         @Override
         public void processRow(ResultSet rs) throws SQLException {
            realProcessRow(rs);
            count++;
         }
      });

这显然无法编译。我知道的两个解决方案都很臭: 我不想计算一个类字段,因为它实际上是一个我需要用于记录目的的局部变量。 我不想数数数组,因为它很难看。

这只是愚蠢的,必须有一个合理的方法来做到这一点?

3 个答案:

答案 0 :(得分:5)

第三种可能性是使用final-mutable-int-object,例如:

final AtomicInteger count = new AtomicInteger(0);
....
count.incrementAndGet();

Apache Commons也有一个MutableInteger我相信,但我还没有使用它。

答案 1 :(得分:2)

你似乎已经意识到这些解决方案(虽然它们不同);并且你可能知道原因(它不能通过引用捕获局部变量,因为在闭包运行时变量可能不存在,所以它必须按值捕获(有多个副本);拥有相同的变量是不好的请参考不同范围内的不同副本,每个副本可以单独更改,因此无法更改。

如果你的闭包不需要将状态共享回封闭范围,那么类中的一个字段是正确的。我不明白你的反对意见。如果闭包需要能够被多次调用并且每次都需要递增,那么它需要在对象中保持状态。字段(实例变量)正确表示在对象中存储状态。可以使用来自外部范围的捕获值初始化该字段。

如果你的闭包需要将状态共享回封闭范围(这不是一个非常常见的情况),那么使用可变结构(如数组)是正确的做法,因为它避免了生命周期的问题局部变量。

答案 2 :(得分:0)

我通常会计算一个类字段,但添加一条注释,它只是一个字段,因为它由内部闭包,Runnable等使用...