日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 8中Lambda表达式的阴暗面

發布時間:2023/12/3 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 8中Lambda表达式的阴暗面 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文章可能不會使我成為任何新朋友。 哦,好吧,無論如何我從來沒有真正在學校受到歡迎。 但是,讓我們說清楚。 就語言而言,Java 8的最大特色無疑是Lambda表達式。 幾年來,它一直是功能語言(例如Scala和Clojure)的旗艦功能,現在Java終于加入了。

第二大功能(當然取決于您問誰)是Nashorn –新的JVM JavaScript引擎,可以使Java與其他JS引擎(例如V8和它的node.js容器)相提并論。

但是這些新功能對他們不利。

我會解釋。 Java平臺由兩個主要組件構建而成。 JIT編譯并執行字節碼的JRE,JDK包含開發工具和javac源代碼編譯器。 這兩個組件是完全(但不是完全)分離的,這使人們能夠編寫自己的JVM語言,而Scala在最近幾年中日益受到關注。 其中存在一些問題。

JVM被構建為與語言無關,只要它可以轉換為字節碼,就可以執行以任何語言編寫的代碼。 字節碼規范本身是完全面向對象的,旨在與Java語言緊密匹配。 這意味著從Java源代碼編譯的字節碼在結構上將非常類似于它。

但是與Java的距離越遠,距離就越遠。 當您查看Scala是一種功能語言時,源代碼與執行的字節碼之間的距離就很大。 編譯器添加了大量合成類,方法和變量,以使JVM執行該語言所需的語義和流控制。

當您查看完全動態的語言(例如JavaScript)時 ,這種距離變得很大。

而現在有了Java 8,它也開始滲透到Java中。

那我為什么要在乎呢?

我希望這是一個理論性的討論,盡管有趣,但對我們的日常工作沒有實際意義。 不幸的是,它確實以很大的方式做到了。 隨著向Java中添加新元素的推動,代碼與運行時之間的距離越來越大,這意味著您正在編寫的內容和正在調試的內容將是兩件事。

要了解讓我們如何(重新)訪問下面的示例。

Java 6和7

這是傳統的方法,通過該方法我們可以遍歷一串字符串以映射其長度。

// simple check against empty strings public static int check(String s) {if (s.equals("")) {throw new IllegalArgumentException();}return s.length(); }//map names to lengthsList lengths = new ArrayList();for (String name : Arrays.asList(args)) {lengths.add(check(name)); }

如果傳遞一個空字符串,這將引發異常。 堆棧跟蹤看起來像–

at LmbdaMain.check(LmbdaMain.java:19) at LmbdaMain.main(LmbdaMain.java:34)

在這里,我們看到了所看到的堆棧跟蹤與所編寫的代碼之間的1:1關系,這使得調試此調用堆棧非常簡單。 這就是大多數Java開發人員所習慣的。

現在讓我們看一下Scala和Java 8。

斯卡拉

讓我們看看Scala中的相同代碼。 在這里,我們有兩個重大變化。 第一個是使用Lambda表達式映射長度,第二個是迭代是由框架執行的(即內部迭代)。

val lengths = names.map(name => check(name.length))

在這里,我們真的開始注意到您編寫的代碼外觀與JVM(以及您)在運行時如何看到它們之間的區別。 如果拋出異常,則調用堆棧會長一個數量級 ,并且很難理解。

at Main$.check(Main.scala:6) at Main$$anonfun$1.apply(Main.scala:12) at Main$$anonfun$1.apply(Main.scala:12) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at Main$delayedInit$body.apply(Main.scala:12) at scala.Function0$class.apply$mcV$sp(Function0.scala:40) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.App$$anonfun$main$1.apply(App.scala:71) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) at scala.App$class.main(App.scala:71) at Main$.main(Main.scala:1) at Main.main(Main.scala)

*請記住,此示例非常簡單。 使用現實世界中的嵌套Lambda和復雜結構,您將需要更長的綜合調用堆棧,您需要從中了解發生了什么。

長期以來,Scala一直是一個問題,這也是我們構建Scala Stackifier的原因之一。

現在在Java 8中

直到現在,Java開發人員都對此免疫。 隨著Lambda表達式成為Java不可或缺的一部分,這種情況將會改變。 讓我們看一下相應的Java 8代碼以及生成的調用堆棧。

Stream lengths = names.stream().map(name -> check(name));at LmbdaMain.check(LmbdaMain.java:19) at LmbdaMain.lambda$0(LmbdaMain.java:37) at LmbdaMain$$Lambda$1/821270929.apply(Unknown Source) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.LongPipeline.reduce(LongPipeline.java:438) at java.util.stream.LongPipeline.sum(LongPipeline.java:396) at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526) at LmbdaMain.main(LmbdaMain.java:39)

這與Scala變得非常相似。 我們為更短,更簡潔的代碼,更復雜的調試和更長的綜合調用堆棧付出了代價。

原因是,盡管javac已擴展為支持Lambda函數,但JVM仍然它們不了解 。 這是Java人士的一項設計決策,目的是保持JVM在較低級別運行,而又不會在其規范中引入新的元素。

盡管您可以辯論此決定的優缺點,但這意味著作為Java開發人員,無論我們是否愿意,當我們拿到罰單時弄清楚這些調用堆棧的成本現在都落在我們肩上。

Java 8中JavaScript

Java 8引入了全新JavaScript編譯器。 現在,我們終于可以以高效,直接的方式集成Java + JS。 但是,我們編寫的代碼與我們調試的代碼之間的不協調之處比這里更大。

這與Nashorn中的功能相同–

ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("nashorn");String js = "var map = Array.prototype.map \n"; js += "var a = map.call(names, function(name) { return Java.type(\"LmbdaMain\").check(name) }) \n"; js += "print(a)"; engine.eval(js);

在這種情況下,字節代碼是在運行時使用Lambda表達式的嵌套樹動態生成的 。 我們的源代碼與由JVM執行的結果字節碼之間幾乎沒有關聯。 現在,調用堆棧要長兩個數量級 。 用T先生的凄美的話語- 我可憐那些需要調試調用堆棧的傻瓜 ,您將到達這里。

有任何疑問嗎? (假設您可以一直滾動到此調用堆棧下方)。 在評論部分讓我知道。

LmbdaMain [Java Application] LmbdaMain at localhost:51287 Thread [main] (Suspended (breakpoint at line 16 in LmbdaMain)) LmbdaMain.wrap(String) line: 16 1525037790.invokeStatic_L_I(Object, Object) line: not available 1150538133.invokeSpecial_LL_I(Object, Object, Object) line: not available 538592647.invoke_LL_I(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 2150540.interpret_I(MethodHandle, Object, Object) line: not available 538592647.invoke_LL_I(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 92150540.interpret_I(MethodHandle, Object, Object) line: not available 38592647.invoke_LL_I(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 731260860.interpret_L(MethodHandle, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LL_L(MethodHandle, Object[]) line: 1108 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 2619171.interpret_L(MethodHandle, Object, Object, Object) line: not available 1597655940.invokeSpecial_LLLL_L(Object, Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLLL_L(MethodHandle, Object[]) line: 1118 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 2619171.interpret_L(MethodHandle, Object, Object, Object) line: not available 1353530305.linkToCallSite(Object, Object, Object, Object) line: not available Script$\^eval\_._L3(ScriptFunction, Object, Object) line: 3 1596000437.invokeStatic_LLL_L(Object, Object, Object, Object) line: not available 1597655940.invokeSpecial_LLLL_L(Object, Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLLL_L(MethodHandle, Object[]) line: 1118 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 484673893.interpret_L(MethodHandle, Object, Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLLLL_L(MethodHandle, Object[]) line: 1123 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 282496973.interpret_L(MethodHandle, Object, Object, Object, long, Object) line: not available 93508253.invokeSpecial_LLLLJL_L(Object, Object, Object, Object, Object, long, Object) line: not available 1850777594.invoke_LLLLJL_L(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 282496973.interpret_L(MethodHandle, Object, Object, Object, long, Object) line: not available 293508253.invokeSpecial_LLLLJL_L(Object, Object, Object, Object, Object, long, Object) line: not available 1850777594.invoke_LLLLJL_L(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 1840903588.interpret_L(MethodHandle, Object, Object, Object, Object, long, Object) line: not available 2063763486.reinvoke(Object, Object, Object, Object, Object, long, Object) line: not available 850777594.invoke_LLLLJL_L(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 82496973.interpret_L(MethodHandle, Object, Object, Object, long, Object) line: not available 220309324.invokeExact_MT(Object, Object, Object, Object, long, Object, Object) line: not available NativeArray$10.forEach(Object, long) line: 1304 NativeArray$10(IteratorAction).apply() line: 124 NativeArray.map(Object, Object, Object) line: 1315 1596000437.invokeStatic_LLL_L(Object, Object, Object, Object) line: not available 504858437.invokeExact_MT(Object, Object, Object, Object, Object) line: not available FinalScriptFunctionData(ScriptFunctionData).invoke(ScriptFunction, Object, Object...) line: 522 ScriptFunctionImpl(ScriptFunction).invoke(Object, Object...) line: 207 ScriptRuntime.apply(ScriptFunction, Object, Object...) line: 378 NativeFunction.call(Object, Object...) line: 161 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available 1740189450.invokeSpecial_LLL_L(Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLL_L(MethodHandle, Object[]) line: 1113 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 2619171.interpret_L(MethodHandle, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLL_L(MethodHandle, Object[]) line: 1113 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 323326911.interpret_L(MethodHandle, Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLLL_L(MethodHandle, Object[]) line: 1118 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 323326911.interpret_L(MethodHandle, Object, Object, Object, Object) line: not available 263793464.invokeSpecial_LLLLL_L(Object, Object, Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLLLL_L(MethodHandle, Object[]) line: 1123 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 1484673893.interpret_L(MethodHandle, Object, Object, Object, Object, Object) line: not available 587003819.invokeSpecial_LLLLLL_L(Object, Object, Object, Object, Object, Object, Object) line: not available 811301908.invoke_LLLLLL_L(MethodHandle, Object[]) line: not available 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 484673893.interpret_L(MethodHandle, Object, Object, Object, Object, Object) line: not available LambdaForm$NamedFunction.invoke_LLLLL_L(MethodHandle, Object[]) line: 1123 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available LambdaForm$NamedFunction.invokeWithArguments(Object...) line: 1147 LambdaForm.interpretName(LambdaForm$Name, Object[]) line: 625 LambdaForm.interpretWithArguments(Object...) line: 604 323326911.interpret_L(MethodHandle, Object, Object, Object, Object) line: not available 2129144075.linkToCallSite(Object, Object, Object, Object, Object) line: not available Script$\^eval\_.runScript(ScriptFunction, Object) line: 3 1076496284.invokeStatic_LL_L(Object, Object, Object) line: not available 1709804316.invokeExact_MT(Object, Object, Object, Object) line: not available FinalScriptFunctionData(ScriptFunctionData).invoke(ScriptFunction, Object, Object...) line: 498 ScriptFunctionImpl(ScriptFunction).invoke(Object, Object...) line: 207 ScriptRuntime.apply(ScriptFunction, Object, Object...) line: 378 NashornScriptEngine.evalImpl(ScriptFunction, ScriptContext, ScriptObject) line: 544 NashornScriptEngine.evalImpl(ScriptFunction, ScriptContext) line: 526 NashornScriptEngine.evalImpl(Source, ScriptContext) line: 522 NashornScriptEngine.eval(String, ScriptContext) line: 193 NashornScriptEngine(AbstractScriptEngine).eval(String) line: 264 LmbdaMain.main(String[]) line: 44

翻譯自: https://www.javacodegeeks.com/2014/03/the-dark-side-of-lambda-expressions-in-java-8.html

總結

以上是生活随笔為你收集整理的Java 8中Lambda表达式的阴暗面的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。