2016-02-17 50 views
1

我總是有我的變量重新分配給標記爲final另一個變量:如何使用lambda而不將變量重新分配給最終變量?

public void method(int myvar) { 

    myvar = myvar + 1; 

    doSomething(myvar); //I need to change myvar before the lambda 

    final int newvar = myvar; //this line is stupid 
    //could be something like: 
    //makefinal myvar; 

    open(con -> { 
     doOtherThing(newVar); 
    }); 
} 

將是非常巨大的,如果有另一種方式來聲明,我的變量不會在open調用之前可以更改。

+0

可以說我需要在'open'之前執行'myvar + 1' – melanke

+0

在這種情況下,您應該使用其他變量,原因與上述相同。 lambda表達式只能使用'final'變量。 – Paul

+0

如果我可以用特定的方式標記myvar來告訴它在'open'之前是最終的,而不是分配給另一個變量 – melanke

回答

5

你不能。這在JLS section 15.27.2明確地指定:

任何局部變量,形參,或使用的異常參數而不是在一個lambda表達式聲明必須被聲明爲final或有效地最終(§4.12.4),或在嘗試使用的地方發生編譯時錯誤。

但是你可以重寫你的榜樣以下幾點:

public void method(int myvar) { 
    final int newvar = myvar + 1; 
    doSomething(newvar); 
    open(con -> doOtherThing(newvar)); 
} 

我們只是聲明一個變量finalnewvar將被重用。

+0

我編輯了示例 – melanke

+0

@melanke請參閱我的編輯。我仍然沒有看到問題。 – Tunaki

2

一個lambda只能訪問變量和方法參數,這些變量和方法參數來自於final或「有效最終」的封閉上下文。後者是指在其範圍內從不修改的變量和參數。這裏很重要的一點是,標準在使用lambda之前不是「沒有變化」,而是從來沒有在它的值被首次設置後改變。

0

,如果你不是特別喜歡做的另一個變量,如何使用一個輔助方法來創建/返回要傳遞到open(...),像這樣的拉姆達:

public static <T> Consumer<T> helper(IntFunction<T> func, int var) { 
    return con -> func.apply(var); 
} 

,然後你可以使用它像這樣:

public void method(int myvar) { 
    myvar = myvar + 1; 
    doSomething(myvar); //I need to change myvar before the lambda 
    open(helper(arg -> doOtherThing(arg), myvar)); 
} 

如果我得到的類型錯誤,您可以更改任何適當的功能接口。您也可以使用方法參考將doOtherThing方法傳遞到helper(...)