Home > Article > Backend Development > 为什么Java闭包不能通过返回值之外的方式向外传递值?
String a; ........(()->a="a"); return a; 为什么不行,是存在技术问题么? 其它语言可以么?c#可以么?莫非从此我要Java一生黑? 至于我为什么问这个问题嘛,就是一个方法有可能有返回值,有可能没有返回值,这就要写两次,还不能同名,写成void和Object两个简直太不优雅。 这个方法其实就是jdbc事务,有查询有不查询,我把事务回滚,异常,日志等写在了一个函数里,这个函数调用这个函数式接口,以后就只要写事务,不用再写回滚,记录日志等操作了。 现在我写了两个方法,感觉很不爽:-(
<code class="language-text">String[] a = new String[1];
... ( () -> a[0] = "a" );
return a[0];
</code>
<code class="language-java"><span class="cm">/* 你可以用AtomicReference将你所需要的值包装起来 */</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">sum</span><span class="o">(</span><span class="kt">int</span> <span class="n">low</span><span class="o">,</span> <span class="kt">int</span> <span class="n">high</span><span class="o">)</span> <span class="o">{</span>
<span class="n">AtomicReference</span><span class="o"><span class="n">Integer</span><span class="o">></span> <span class="n">sum</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AtomicReference</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
<span class="n">IntStream</span><span class="o">.</span><span class="na">rangeClosed</span><span class="o">(</span><span class="n">low</span><span class="o">,</span> <span class="n">high</span><span class="o">).</span><span class="na">forEach</span><span class="o">(</span><span class="n">i</span> <span class="o">-></span> <span class="n">sum</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">sum</span><span class="o">.</span><span class="na">get</span><span class="o">()</span> <span class="o">+</span> <span class="n">i</span><span class="o">));</span>
<span class="k">return</span> <span class="n">sum</span><span class="o">.</span><span class="na">get</span><span class="o">();</span>
<span class="o">}</span>
<span class="cm">/* 对于基本类型有专用的包装类更方便使用(且是原子化操作) */</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">sum2</span><span class="o">(</span><span class="kt">int</span> <span class="n">low</span><span class="o">,</span> <span class="kt">int</span> <span class="n">high</span><span class="o">)</span> <span class="o">{</span>
<span class="n">AtomicInteger</span> <span class="n">sum</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AtomicInteger</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
<span class="n">IntStream</span><span class="o">.</span><span class="na">rangeClosed</span><span class="o">(</span><span class="n">low</span><span class="o">,</span> <span class="n">high</span><span class="o">).</span><span class="na">forEach</span><span class="o">(</span><span class="n">sum</span><span class="o">::</span><span class="n">addAndGet</span><span class="o">);</span>
<span class="k">return</span> <span class="n">sum</span><span class="o">.</span><span class="na">get</span><span class="o">();</span>
<span class="o">}</span>
<span class="cm">/* 其实很多时候,我们并不需要改变外部状态不是吗? */</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">sum3</span><span class="o">(</span><span class="kt">int</span> <span class="n">low</span><span class="o">,</span> <span class="kt">int</span> <span class="n">high</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">IntStream</span><span class="o">.</span><span class="na">rangeClosed</span><span class="o">(</span><span class="n">low</span><span class="o">,</span> <span class="n">high</span><span class="o">).</span><span class="na">sum</span><span class="o">();</span>
<span class="o">}</span>
</span></code>
C++:可以
C#:可以
F#:可以
VB:可以
补充 @vczh<code class="language-java"><span class="kt">void</span> <span class="n">SomeObject</span> <span class="nf">someMethod</span><span class="o">(</span><span class="n">Supplier</span><span class="o"><span class="n">Optional</span><span class="o"><span class="n">Object</span><span class="o">>></span> <span class="n">foo</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">foo</span><span class="o">.</span><span class="na">get</span><span class="o">().</span><span class="na">map</span><span class="o">(</span><span class="n">a</span> <span class="o">-></span> <span class="o">((</span><span class="n">Object</span> <span class="n">a</span><span class="o">)</span> <span class="o">-></span> <span class="o">...)).</span><span class="na">orElseGet</span><span class="o">(()</span> <span class="o">-></span> <span class="o">...);</span>
<span class="o">}</span>
</span></span></code>
java的函数无法进行引用传递,闭包的捕获也一样。so sad。
什么叫"不能向外传递值"?