4

我想编写以下代码:

boolean found = false;
search(new SearchCallback() {
  @Override void onFound(Object o) { found = true; }
});

显然这是不允许的,因为found需要finalfound出于线程安全的原因,我无法创建成员字段。什么是最好的选择?一种解决方法是定义

final class MutableReference<T> {
  private T value;
  MutableReference(T value) { this.value = value; }
  T get() { return value; }
  void set(T value) { this.value = value; }
}

但这最终会在正确格式化时占用大量空间,如果可能的话,我宁愿不重新发明轮子。我可以将 aList<Boolean>与单个元素一起使用(改变该元素,或者清空列表),甚至可以使用Boolean[1]. 但一切似乎都闻起来很有趣,因为没有一个选项按预期使用。

这样做的合理方法是什么?

4

4 回答 4

4

我倾向于使用您提到的 boolean[1] 方法:

final boolean[] found = {false};
search(new SearchCallback() {
  @Override void onFound(Object o) { found[0] = true; }
});

这有点hackish,但它往往是最接近你真正想要的东西

于 2010-05-04T02:48:38.803 回答
3

你可以去所有功能:

Boolean found = search(new SearchCallback<Boolean>() {
    @Override Boolean onFound(Object o) { return true; }
});

通常如果你想改变一个封闭变量,你可以不这样做更清楚地表达一个解决方案。

于 2010-05-04T03:34:19.883 回答
2

所有的解决方案确实都是骇人听闻的,但数组是处理它的“标准”教科书方式,因为即使是前泛型它也是类型安全的。

在这种情况下,另一种选择是像这样创建一个私有类:

   private class Searcher implements SearchCallback {
        private boolean found;
        @Override public void onFound(Object o) { found = true; }
        public boolean search() {
              OuterClass.this.search(this);
              return found;
        }
   }

然后像这样使用它:

  boolean found = new Searcher().search();

编辑:如果我正确理解汤姆的评论,他建议将此作为替代

 public void foo() { //This is the method that enclosed the code in your question
     new SearchCallBack() {
         private boolean found;
         @Override public void onFound(Object o) { found = true; }
         {
            //The code that was before this in your method
            search(this);
            //The code that was after this in your method
         }
     };
 }

我认为这更骇人听闻,我真的会发现这样的代码不寻常,但绝对值得知道它是一种选择。

于 2010-05-04T03:00:32.833 回答
0

如果您真的不能使用字段,迈克尔的回答似乎是正确的。

反正。我不知道您可以触摸哪些签名,但在我看来,该回调旨在对找到的对象执行某些操作(当搜索成功时)。相反,您打算通知搜索方法的调用者它找到了一些东西。如果您的seach()方法返回一个布尔值(如果搜索成功,该方法肯定会在某处调用 s.onFound() ,然后在那里设置一个内部found标志并返回它),这似乎更自然。

于 2010-05-04T03:04:51.670 回答