从匿名 Java 类改变原始变量的合理方法是什么?
我想编写以下代码:
boolean found = false;
search(new SearchCallback() {
@Override void onFound(Object o) { found = true; }
});
显然这是不允许的,因为 found
需要是 final
。出于线程安全原因,我无法将 found
设置为成员字段。最好的选择是什么?一种解决方法是定义,
final class MutableReference<T> {
private T value;
MutableReference(T value) { this.value = value; }
T get() { return value; }
void set(T value) { this.value = value; }
}
但如果格式正确,这最终会占用大量空间,如果可能的话,我宁愿不重新发明轮子。我可以将 List
与单个元素一起使用(要么改变该元素,要么清空列表),甚至可以使用 Boolean[1]
。但一切似乎都很奇怪,因为没有一个选项按照预期使用。
这样做的合理方法是什么?
I would like to write the following code:
boolean found = false;
search(new SearchCallback() {
@Override void onFound(Object o) { found = true; }
});
Obviously this is not allowed, since found
needs to be final
. I can't make found
a member field for thread-safety reasons. What is the best alternative? One workaround is to define
final class MutableReference<T> {
private T value;
MutableReference(T value) { this.value = value; }
T get() { return value; }
void set(T value) { this.value = value; }
}
but this ends up taking a lot of space when formatted properly, and I'd rather not reinvent the wheel if at all possible. I could use a List<Boolean>
with a single element (either mutating that element, or else emptying the list) or even a Boolean[1]
. But everything seems to smell funny, since none of the options are being used as they were intended.
What is a reasonable way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我倾向于使用您提到的 boolean[1] 方法:
这有点黑客,但它往往是最接近您实际想要的东西
I tend to do the boolean[1] method you mentioned:
It's a bit hackish, but it tends to be the closest thing to what you actually want
你可以使用所有功能:
通常,如果你想改变一个封闭变量,你可以通过不这样做来更清楚地表达解决方案。
You could go all functional:
Usually if you want to mutate an enclosing variable, you can express a solution more clearly by not doing so.
所有解决方案确实都是 hackish,但数组是处理它的“标准”教科书方式,因为即使在泛型之前它也是类型安全的。
在这种情况下的另一个选择是像这样创建一个私有类:
然后像这样使用它:
编辑:如果我正确理解汤姆的评论,他建议将此作为替代方案
我认为这更黑客,我真的会找到这样的代码不寻常,但绝对值得知道它是一种选择。
All solutions are indeed hackish, but the array is the "standard" textbook way of handling it, as even pre-generics it was typesafe.
Another option in this situation is to make a private class like so:
And then use it like so:
Edit: If I understand Tom's comment correctly, he is suggesting this as an alternative
I think that is more hackish and I would really find such code unusual, but it is definitely worth knowing that it is an option.
如果你真的不能使用字段,迈克尔的回答似乎是正确的。
反正。我不知道您可以触摸哪些签名,但在我看来,该回调旨在对找到的对象执行某些操作(当搜索成功时)。相反,您打算通知搜索方法的调用者它发现了某些内容。如果您的 seach() 方法返回一个布尔值,那么看起来会更自然(如果搜索成功,该方法肯定会在某个地方调用 s.onFound() ,然后设置一个内部 found 在那里标记并返回)。
If you really cant use a field, Michael answers seems right.
Anyway. I dont know what signatures you can touch, but it seems to me that that callback is intented to do something (when the search succeeds) with/to the found object. You, instead, are intending to notify the caller of the search method that it found something. It would seems much more natural if your seach() method were made to return a boolean (the method will surely call s.onFound() somewhere if the search succeeds, then set an internal found flag there and return it).