将变量更改为lambda java中的lambda表达式范围

时间:2018-06-13 07:26:08

标签: java lambda

我有一个发送到另一个函数的lambda函数,我想在lambda中更改一个在lambda范围之外声明的变量。

    WebElement  textArea ;
    BrowserToucher.clickOnWebElement(() -> {
        WebElement convPopupOrCard = findElementBy(driver, 
            conversationCardOrPopup);
        return textArea = findSubElementBy(driver, convPopupOrCard, 
            CardAndPopupTextArea);  
        }, driver);
    BrowserToucher.sendKeys(textArea, driver, text);

我需要更改' textArea' labmda中的var,所以我可以在最后一行使用它的值。

我找到的唯一解决方案是制作“textArea”字样'一个大小为1的数组。 但我真的不明白为什么会这样。 如果有人可以向我解释,请爱。 谢谢!!

3 个答案:

答案 0 :(得分:2)

  

我发现的唯一解决方案是让'textArea'成为一个大小为1的数组但是我真的不明白它为什么会起作用。

它的工作原理是因为捕获的数组本身是 final 有效的最终(任何值不会改变的变量)。

只要捕获的变量 final 有效地最终,更改数组的内容就完全没问题了。允许的。

当然,像这样的代码不是线程安全的。因此,理想情况下,在使用此技巧之前,您应该三思而后行。

答案 1 :(得分:1)

如果我正确理解你的问题,如果你记得lambdas只是函数但是没有名字,那么解决方案就不那么难了,所以你可以在括号中传递任何参数,就像你使用' regular&#39 ; java方法。

  

我找到的唯一解决方案是制作“textArea”字样'一个大小为的数组   但我真的不明白为什么会有效。

在关于java引用的堆栈溢出主题之一中已经很好地描述了这一点。请熟悉它,你会很好地理解它,并且maby为你的问题提出了另一种解决方案:)

Is Java "pass-by-reference" or "pass-by-value"?

答案 2 :(得分:1)

lambda或任何匿名内部类中的变量需要是最终的或有效的最终。

这是因为这些变量被复制到lambda范围。如果引用它们而不是复制它们,当变量超出其声明区域的范围时会出现问题,而lambda范围仍然在执行(想想线程)。

通过定义一个数组,你正在解决这个问题:你强行引用这个值,使用一个有效的最终数组(你初始化数组一次,永远不要改变它)。

最终和有效的最终变量可以安全地复制,因为它们的价值不会改变。

当数组超出范围时没问题,GC仍然保留一个指向lambda范围内的值的指针,并且它不会被垃圾收集,直到lambda和声明区都超出范围。

您可以对列表或任何其他集合执行相同操作。它也适用于包装类。