lambda表达式中使用的变量应该是final或有效final
当我尝试使用calTz时,它显示了这个错误。
private TimeZone extractCalendarTimeZoneComponent(Calendar cal, TimeZone calTz) {
try {
cal.getComponents().getComponents("VTIMEZONE").forEach(component -> {
VTimeZone v = (VTimeZone) component;
v.getTimeZoneId();
if (calTz == null) {
calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue());
}
});
} catch (Exception e) {
log.warn("Unable to determine ical timezone", e);
}
return null;
}
final变量意味着它只能被实例化一次。
在Java中,你不能在lambda和匿名内部类中重新分配非最终局部变量。
你可以用旧的for-each循环重构你的代码:
private TimeZone extractCalendarTimeZoneComponent(Calendar cal,TimeZone calTz) {
try {
for(Component component : cal.getComponents().getComponents("VTIMEZONE")) {
VTimeZone v = (VTimeZone) component;
v.getTimeZoneId();
if(calTz==null) {
calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue());
}
}
} catch (Exception e) {
log.warn("Unable to determine ical timezone", e);
}
return null;
}
即使我不明白这段代码的某些部分:
你调用v.getTimeZoneId();不使用它的返回值
赋值calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue());你不会修改最初传递的calTz,也不会在这个方法中使用它
你总是返回null,为什么不把void设为返回类型呢?
希望这些建议也能帮助你提高。
在您的示例中,您可以使用简单的for循环将forEach替换为lamdba,并自由修改任何变量。或者重构代码,这样就不需要修改任何变量。但是,为了完整起见,我将解释这个错误的含义以及如何解决它。
Java 8语言规范,§15.27.2:
在lambda表达式中使用但未声明的任何局部变量、形式形参或异常形参必须声明为final或有效的final(§4.12.4),否则尝试使用时将发生编译时错误。
基本上,您不能在lambda(或本地/匿名类)内修改局部变量(在本例中为calTz)。要在Java中实现这一点,必须使用可变对象并从lambda中修改它(通过final变量)。可变对象的一个例子是一个元素数组:
private TimeZone extractCalendarTimeZoneComponent(Calendar cal, TimeZone calTz) {
TimeZone[] result = { null };
try {
cal.getComponents().getComponents("VTIMEZONE").forEach(component -> {
...
result[0] = ...;
...
}
} catch (Exception e) {
log.warn("Unable to determine ical timezone", e);
}
return result[0];
}
final变量意味着它只能被实例化一次。
在Java中,你不能在lambda和匿名内部类中重新分配非最终局部变量。
你可以用旧的for-each循环重构你的代码:
private TimeZone extractCalendarTimeZoneComponent(Calendar cal,TimeZone calTz) {
try {
for(Component component : cal.getComponents().getComponents("VTIMEZONE")) {
VTimeZone v = (VTimeZone) component;
v.getTimeZoneId();
if(calTz==null) {
calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue());
}
}
} catch (Exception e) {
log.warn("Unable to determine ical timezone", e);
}
return null;
}
即使我不明白这段代码的某些部分:
你调用v.getTimeZoneId();不使用它的返回值
赋值calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue());你不会修改最初传递的calTz,也不会在这个方法中使用它
你总是返回null,为什么不把void设为返回类型呢?
希望这些建议也能帮助你提高。