2 回答
TA贡献1775条经验 获得超8个赞
就我而言(Java12),我在 和 中都遇到了DoubleUnaryOperator
错误UnaryOperator
。
您的情况是,您正在重新分配doub
withoo
函数结果,然后尝试使用doub
in next 运算符。
我引用的是:最终和有效最终之间的区别
通俗地说,如果局部变量的初始值从未改变,那么它实际上就是final的——换句话说,将其声明为final不会导致编译失败。
所以,经过检查我明白的是:
如果变量是final
,则它始终可以在 lambda 表达式中使用,因为不可能重新分配它(有 - 反射,但这是另一个主题)。
effectively final
当声明的变量保持不变时,该变量就会出现。
如果您将 的结果分配oo
给新声明的变量,那么您应该能够在o
.
我相信您试图实现10.6
价值,示例如下:
double doub = 10.0;
DoubleUnaryOperator oo = d -> {
return doub + d;
};
double ahh = oo.applyAsDouble(.3);
UnaryOperator<Double> o = d -> {
return ahh + d;
};
System.out.println(o.apply(.3)); //The o.apply(.3) can be assigned to new variable
任何重新分配doub或ahh导致编译错误 (Java11)
TA贡献1802条经验 获得超5个赞
我无法重现您的声明,即一个编译而另一个不编译。对我来说,两者都不能编译。
信息:java:编译模块“tuts”时发生错误信息:javac 1.8.0_192用于编译java源信息:9/14/2019 8:10 PM - 构建完成,2秒849毫秒C内有1个错误和0个警告:\Users\Philip\Code\tuts\src\test\java\tuts\UnaryOperatorTest.java 错误:(13, 60) java: 从 lambda 表达式引用的局部变量必须是最终的或有效的最终
doub
问题是,在使用 的 lambda 中创建新作用域后,您尝试在外部作用域中重新分配 to doub
。
doub
如果您可以在 lambda 范围之外更改 的值,则 lambda 的功能将变得不确定。因此,来自外部作用域的值必须被声明final
或者是“有效”最终的(意味着您遵循规则并且不要尝试在外部作用域中重新分配给它们)。
如果您只需将结果分配给不同的变量(result
,在下面的示例中),您就可以使用两种替代方案:
import org.junit.Assert;
import org.junit.Test;
import java.util.function.DoubleUnaryOperator;
import java.util.function.UnaryOperator;
public class UnaryOperatorTest {
@Test
public void testDoubleUnaryOperator() {
double doub = 10.0;
DoubleUnaryOperator doubleUnaryOperator = d -> d + doub;
double result = doubleUnaryOperator.applyAsDouble(0.3);
Assert.assertEquals(10.3, result, Double.MIN_VALUE);
}
@Test
public void testUnaryOperator() {
double doub = 10.0;
UnaryOperator<Double> unaryOperator = d -> d + doub;
double result = unaryOperator.apply(0.3);
Assert.assertEquals(10.3, result, Double.MIN_VALUE);
}
}
(编辑)我已逐字复制并粘贴您的代码。FunctionalInterface
从有问题的行号(31 和 36)可以看出,这两个示例 都无法在 Java 8 中编译:
然而,doub
通过分配 to 来有效地实现最终result
允许代码编译:
添加回答
举报