[英]Assign a value to a final variable
Suppose I have this code: 假设我有以下代码:
public HttpResponse myFunction(...) {
final HttpResponse resp;
OnResponseCallback myCallback = new OnResponseCallback() {
public void onResponseReceived(HttpResponse response) {
resp = response;
}
};
// launch operation, result will be returned to myCallback.onResponseReceived()
// wait on a CountDownLatch until operation is finished
return resp;
}
Obviously I can not assign a value to resp from onResponseReceived because it is a final variable, BUT if it was not a final variable onResponseReceived could not see it. 显然,我无法为onResponseReceived赋值,因为它是最终变量,但如果不是最终变量onResponseReceived,则无法看到它。 Then, how can I assign a value to resp from onResponseReceived? 然后,如何从onResponseReceived分配一个值作为resp?
What I thought is to create a wrapper class for enclosing the resp object. 我想的是创建一个封装类来封装resp对象。 The final object would be an instance of this wrapper class and I could assign the value to resp working on the object inside the final class (which is not final). 最终对象将是该包装器类的一个实例,我可以为最终类(不是最终)中的对象分配相应的值。
The code would be this one: 代码就是这样的:
class ResponseWrapper {
HttpResponse resp = null;
}
public HttpResponse myFunction(...) {
final ResponseWrapper respWrap = new ResponseWrapper();
OnResponseCallback myCallback = new OnResponseCallback() {
public void onResponseReceived(HttpResponse response) {
respWrap.resp = response;
}
};
// launch operation, result will be returned to myCallback.onResponseReceived()
// wait on a CountDownLatch until operation is finished
return respWrap.resp;
}
What do you think about this solution? 您如何看待该解决方案?
java.util.concurrent.atomic.AtomicReference java.util.concurrent.atomic.AtomicReference
Standard practice is to use a final AtomicReference, which you can set and get. 标准做法是使用最终的AtomicReference,您可以对其进行设置和获取。 This adds the benefit of thread safety as well :) As you mentioned, a CountDownLatch is helpful in waiting for completion. 这也增加了线程安全性的好处:)正如您提到的,CountDownLatch在等待完成时很有帮助。
Your solution is as valid as any other. 您的解决方案与其他解决方案一样有效。 Other popular choices include the one element array 其他流行的选择包括一个元素数组
final HttpResponse[] resp = new Response[1];
// In the callback
resp[0] = response;
// After the operation
return resp[0];
and the generic wrapper 和通用包装
public class Ref<T> {
public T value;
}
final Ref<HttpResponse> resp;
// In the callback
resp.value = response;
// After the operation
return resp.value;
You can combine the hand-back and the wait into one using a SynchronousQueue
(exception handling omitted) 您可以使用SynchronousQueue
将递归和等待合并为一个(省略了异常处理)
public HttpResponse myFunction(...) {
final Queue<HttpResponse> resp = new SynchronousQueue<HttpResponse>();
OnResponseCallback myCallback = new OnResponseCallback() {
public void onResponseReceived(HttpResponse response) {
resp.put(response);
}
};
return resp.take();
}
The change I would make would be to use an AtomicReference since this is obviously multi-threaded and you wouldn't have to write your own wrapper. 我将进行的更改将使用AtomicReference,因为这显然是多线程的,并且您不必编写自己的包装器。 Otherwise, seems reasonable to me. 否则,对我来说似乎很合理。
You can make it mutable and final ;) The simplest approach is to use na array but an AtomicReference can also be used. 您可以使其可变且最终;)最简单的方法是使用na数组,但也可以使用AtomicReference。
public HttpResponse myFunction(...) {
final HttpResponse[] resp = { null };
OnResponseCallback myCallback = new OnResponseCallback() {
public void onResponseReceived(HttpResponse response) {
resp[0] = response;
}
};
// launch operation, result will be returned to myCallback.onResponseReceived()
// wait on a CountDownLatch as soon as operation is finished
return resp[0];
}
or 要么
public HttpResponse myFunction(...) {
final AtomicReference<HttpResponse> resp = new AtomicReference<HttpResponse>();
OnResponseCallback myCallback = new OnResponseCallback() {
public void onResponseReceived(HttpResponse response) {
resp.set(response);
}
};
// launch operation, result will be returned to myCallback.onResponseReceived()
// wait on a CountDownLatch as soon as operation is finished
return resp.get();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.