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
允許代碼編譯:
添加回答
舉報