亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

封閉范圍內的局部變量具有不同的結果

封閉范圍內的局部變量具有不同的結果

郎朗坤 2023-07-28 16:12:26
比較用于將雙精度數添加到雙精度數的兩個運算符類型:DoubleUnaryOperator和UnaryOperator<Double>:    public void test() {        double doub = 10.0;        // This is OK        DoubleUnaryOperator oo = d -> {            return doub + d;        };                  // Compilation error: Local variable doub defined in an enclosing scope must be final or effectively final        UnaryOperator<Double> o = d -> {            return doub + d;         };        doub = oo.applyAsDouble(.3);        doub = o.apply(.3);    }  為什么只有UnaryOperator<Double>才會出現編譯錯誤(doub不是最終的)?如果變量聲明從未改變,為什么會出現不同的結果?
查看完整描述

2 回答

?
www說

TA貢獻1775條經驗 獲得超8個贊

就我而言(Java12),我在 和 中都遇到了DoubleUnaryOperator錯誤UnaryOperator

您的情況是,您正在重新分配doubwithoo函數結果,然后嘗試使用doubin 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)


查看完整回答
反對 回復 2023-07-28
?
12345678_0001

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 中編譯:

https://img1.sycdn.imooc.com//64c378a000015a8606560503.jpg

然而,doub通過分配 to 來有效地實現最終result允許代碼編譯: 

https://img1.sycdn.imooc.com//64c378b4000181ac06530555.jpg

查看完整回答
反對 回復 2023-07-28
  • 2 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號