为什么我需要在 @Override[inner class] 方法中将变量转换为最终数组?
Why do I need to transform variable into final array inside @Override[inner class] method?
我正在使用以下代码:
public void addConditions(){
final String arriveHourse, departHourse, arriveMinutes, departMinutes;
TimePickerDialog.OnTimeSetListener departOnTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHours, int selectedMinutes) {
departHourse = String.valueOf(selectedHours);
departMinutes = String.valueOf(selectedMinutes);
}
};
...
}
为什么 IDE 要求我将 departHourse
转换为最终数组?
为什么会这样,我该如何避免?
此外,如果我将变量移到 class 之外,它的工作方式如下:
String arriveHourse, departHourse, arriveMinutes, departMinutes;
public void addConditions(){
TimePickerDialog.OnTimeSetListener departOnTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHours, int selectedMinutes) {
departHourse = String.valueOf(selectedHours);
departMinutes = String.valueOf(selectedMinutes);
}
};
...
}
departHourse
是最终变量。它必须是,以便在匿名内部 class 中使用。这意味着您不能在匿名内部 class.
中为其分配新值
解决此问题的一种方法是改为创建单元素数组:
final String[] valueHolder = new String[1];
...
Foo foo = new Foo() {
@Override public void bar() {
valueHolder[0] = "Set in bar";
}
}
另一种方法是使用 AtomicReference
:
final AtomicReference<String> valueHolder = new AtomicReference<String>();
...
Foo foo = new Foo() {
@Override public void bar() {
valueHolder.set("Set in bar");
}
}
在这两种情况下,这允许您在不更改 valueHolder
变量本身的值的情况下提供新信息。
好的描述:http://wiki.c2.com/?ClosuresThatWorkAroundFinalLimitation
最佳答案:Lambdas: local variables need final, instance variables don't
简短描述:正在为 JVM 内的匿名内部 class 实例(命名闭包)复制变量,因此如果它不是最终的,编译器将需要复制每个参数。
在您的情况下,@override
不是您需要将参数声明为 final 的原因,原因是 - 它们在闭包中用作 params/local 变量!
我正在使用以下代码:
public void addConditions(){
final String arriveHourse, departHourse, arriveMinutes, departMinutes;
TimePickerDialog.OnTimeSetListener departOnTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHours, int selectedMinutes) {
departHourse = String.valueOf(selectedHours);
departMinutes = String.valueOf(selectedMinutes);
}
};
...
}
为什么 IDE 要求我将 departHourse
转换为最终数组?
为什么会这样,我该如何避免?
此外,如果我将变量移到 class 之外,它的工作方式如下:
String arriveHourse, departHourse, arriveMinutes, departMinutes;
public void addConditions(){
TimePickerDialog.OnTimeSetListener departOnTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int selectedHours, int selectedMinutes) {
departHourse = String.valueOf(selectedHours);
departMinutes = String.valueOf(selectedMinutes);
}
};
...
}
departHourse
是最终变量。它必须是,以便在匿名内部 class 中使用。这意味着您不能在匿名内部 class.
解决此问题的一种方法是改为创建单元素数组:
final String[] valueHolder = new String[1];
...
Foo foo = new Foo() {
@Override public void bar() {
valueHolder[0] = "Set in bar";
}
}
另一种方法是使用 AtomicReference
:
final AtomicReference<String> valueHolder = new AtomicReference<String>();
...
Foo foo = new Foo() {
@Override public void bar() {
valueHolder.set("Set in bar");
}
}
在这两种情况下,这允许您在不更改 valueHolder
变量本身的值的情况下提供新信息。
好的描述:http://wiki.c2.com/?ClosuresThatWorkAroundFinalLimitation
最佳答案:Lambdas: local variables need final, instance variables don't
简短描述:正在为 JVM 内的匿名内部 class 实例(命名闭包)复制变量,因此如果它不是最终的,编译器将需要复制每个参数。
在您的情况下,@override
不是您需要将参数声明为 final 的原因,原因是 - 它们在闭包中用作 params/local 变量!