重复调用将 Retrofit 网络调用排入队列的静态方法是否会相应地维护传递参数的值?
Does repetitively calling a static method that enqueues a Retrofit network call maintain the value of the passed arguments correspondingly?
public static void sendFeedback(final Feedback feedback, final Context context) {
Call<MyServerResponse> sendFeedbackCall = service.sendFeedback(feedback);
sendFeedbackCall.enqueue(new Callback<MyServerResponse>() {
@Override
public void onResponse(@NonNull Call<MyServerResponse> call, @NonNull Response<MyServerResponse> response) {
if (response.isSuccessful()) {
feedback.setSent(true); // *do more actions on **that feedback object** based on the response body.*
} else {
feedback.setSent(false); // *do more actions on **that feedback object** based on the response body.*
}
}
@Override
public void onFailure(@NonNull Call<MyServerResponse> call, @NonNull Throwable t) {
feedback.setSent(false); // do more actions on **that feedback object** based on the response object.
Toast.makeText(context,"Hello",Toast.LENGTH_SHORT).show(); // use the passed argument **context**
});
}
我通过从 for 循环调用上述静态方法,使用 Retrofit 按顺序向服务器发送反馈类型的多个对象。
当试图访问从回调函数内部反馈的传递参数时,IDE 迫使我将传递的参数设为最终参数。
假设:
现在假设每次网络调用都需要 1 秒,直到我收到响应。但是,由于我使用 for 循环来调用 sendFeedback 静态方法,在 Retrofit 回调方法收到第一个响应之前,它会被调用大约 10 次。
问题:由于该方法将在线程通过 Retrofit 异步调用 returns 响应在其内部初始化之前过早结束。这是否意味着在回调方法中完成的工作将在 for 循环中最后传递的 Feedback 类型的参数上,或者在 null 上,因为该方法无论如何都会在那个时候结束?
但是,我确信自从显示使用上下文的 toast 以来,至少有一个传递的参数存在!请给我一个解释。
为什么 IDE 迫使我将论点作为最终论点?
Java 要求如果要在匿名 class 中使用局部变量,它必须是最终的。基本上,任何时候你的代码看起来像
void myMethod(A a, B b) {
C c = new C();
doSomething(new MyClass() {
void methodInAnonymmousClass() {
a.doSomething();
c.doSomething();
}
});
}
您在匿名 class 中使用的任何局部变量(在本例中为 a 和 c)必须是最终变量。这只是语言的要求。它不会改变您的代码的工作方式。它仍然会按照您期望的方式运行。
首先: 为了从方法内部创建的匿名 class 内部访问任何变量,该变量必须是最终变量。自 Java 8 以来不再需要显式地写 final 关键字,但该变量不得在方法内部更改。所以,毕竟 final 是为你隐式应用的。
其次:每次调用该方法时,该变量都会被复制到匿名class中,以便被创建的匿名classes使用.这就是为什么如果你启动一个线程,它仍然会有变量可以使用,即使方法范围到那时已经结束并且方法参数不再存在。请看下面的代码:
for(int i =0; i<10,i++){
show(i);
}
void show(final int param) {
new Thread(new Runnable() {
public void run() {
try {
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(param);
}
}).start();
}
以上代码将打印:12345678910
相同的概念适用于问题,其中匿名 class 是改造回调。
public static void sendFeedback(final Feedback feedback, final Context context) {
Call<MyServerResponse> sendFeedbackCall = service.sendFeedback(feedback);
sendFeedbackCall.enqueue(new Callback<MyServerResponse>() {
@Override
public void onResponse(@NonNull Call<MyServerResponse> call, @NonNull Response<MyServerResponse> response) {
if (response.isSuccessful()) {
feedback.setSent(true); // *do more actions on **that feedback object** based on the response body.*
} else {
feedback.setSent(false); // *do more actions on **that feedback object** based on the response body.*
}
}
@Override
public void onFailure(@NonNull Call<MyServerResponse> call, @NonNull Throwable t) {
feedback.setSent(false); // do more actions on **that feedback object** based on the response object.
Toast.makeText(context,"Hello",Toast.LENGTH_SHORT).show(); // use the passed argument **context**
});
}
我通过从 for 循环调用上述静态方法,使用 Retrofit 按顺序向服务器发送反馈类型的多个对象。
当试图访问从回调函数内部反馈的传递参数时,IDE 迫使我将传递的参数设为最终参数。
假设:
现在假设每次网络调用都需要 1 秒,直到我收到响应。但是,由于我使用 for 循环来调用 sendFeedback 静态方法,在 Retrofit 回调方法收到第一个响应之前,它会被调用大约 10 次。
问题:由于该方法将在线程通过 Retrofit 异步调用 returns 响应在其内部初始化之前过早结束。这是否意味着在回调方法中完成的工作将在 for 循环中最后传递的 Feedback 类型的参数上,或者在 null 上,因为该方法无论如何都会在那个时候结束?
但是,我确信自从显示使用上下文的 toast 以来,至少有一个传递的参数存在!请给我一个解释。
为什么 IDE 迫使我将论点作为最终论点?
Java 要求如果要在匿名 class 中使用局部变量,它必须是最终的。基本上,任何时候你的代码看起来像
void myMethod(A a, B b) {
C c = new C();
doSomething(new MyClass() {
void methodInAnonymmousClass() {
a.doSomething();
c.doSomething();
}
});
}
您在匿名 class 中使用的任何局部变量(在本例中为 a 和 c)必须是最终变量。这只是语言的要求。它不会改变您的代码的工作方式。它仍然会按照您期望的方式运行。
首先: 为了从方法内部创建的匿名 class 内部访问任何变量,该变量必须是最终变量。自 Java 8 以来不再需要显式地写 final 关键字,但该变量不得在方法内部更改。所以,毕竟 final 是为你隐式应用的。
其次:每次调用该方法时,该变量都会被复制到匿名class中,以便被创建的匿名classes使用.这就是为什么如果你启动一个线程,它仍然会有变量可以使用,即使方法范围到那时已经结束并且方法参数不再存在。请看下面的代码:
for(int i =0; i<10,i++){
show(i);
}
void show(final int param) {
new Thread(new Runnable() {
public void run() {
try {
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(param);
}
}).start();
}
以上代码将打印:12345678910
相同的概念适用于问题,其中匿名 class 是改造回调。