Nashorn如何在新层面上影响API的发展
在上一篇關于如何將jOOQ與Java 8和Nashorn結合使用的文章之后,我們的一位用戶發現了使用jOOQ API的缺陷, 如用戶組中所述 。 本質上,缺陷可以總結如下:
Java代碼
package org.jooq.nashorn.test;public class API {public static void test(String string) {throw new RuntimeException("Don't call this");}public static void test(Integer... args) {System.out.println("OK");} }JavaScript代碼
var API = Java.type("org.jooq.nashorn.test.API"); API.test(1); // This will fail with RuntimeException經過一些調查和Attila Szegedi以及Jim Laskey (來自Oracle的Nashorn開發人員)的友好幫助,很明顯,Nashorn消除了重載方法和vararg的歧義,這與舊Java開發人員所期望的有所不同。 報價阿提拉:
Nashorn的重載方法解析盡可能地模仿Java語言規范(JLS),但也允許特定于JavaScript的轉換。 JLS說,當選擇一種方法來調用重載名稱時,僅當沒有適用的固定arity方法時,才可以考慮使用可變arity方法進行調用。
我同意只有在沒有適用的固定arity方法時才可以考慮使用可變arity方法。 但是,由于使用ToString , ToNumber , ToBoolean進行類型提升(或強制/轉換),因此“適用”本身的整個概念已被完全更改,而不是直觀上看起來與varargs方法“完全”匹配的對象更喜歡 !
讓它沉下去!
既然我們現在知道Nashorn如何解決過載,我們可以看到以下任何一種有效的解決方法:
使用數組參數明確調用test(Integer [])方法:
這是最簡單的方法,您可以忽略存在可變參數的事實,而只需創建一個顯式數組即可:
var API = Java.type("org.jooq.nashorn.test.API"); API.test([1]);這樣明確地調用test(Integer [])方法:
這無疑是最安全的方法,因為您要消除方法調用中的所有歧義:
var API = Java.type("org.jooq.nashorn.test.API"); API["test(Integer[])"](1);消除過載:
public class AlternativeAPI1 {public static void test(Integer... args) {System.out.println("OK");} }刪除可變參數:
public class AlternativeAPI3 {public static void test(String string) {throw new RuntimeException("Don't call this");}public static void test(Integer args) {System.out.println("OK");} }提供確切的選擇:
public class AlternativeAPI4 {public static void test(String string) {throw new RuntimeException("Don't call this");}public static void test(Integer args) {test(new Integer[] { args });}public static void test(Integer... args) {System.out.println("OK");} }用CharSequence(或任何其他“相似類型”)替換String:
現在,這很有趣:
public class AlternativeAPI5 {public static void test(CharSequence string) {throw new RuntimeException("Don't call this");}public static void test(Integer args) {System.out.println("OK");} }具體來說,我認為從Java角度來看, CharSequence和String類型之間的區別似乎是非常隨機的。
商定,即使有可能,也很難用動態類型的語言實現重載的方法解析。 任何解決方案都是一種折衷方案,它將在某些方面引入缺陷。 或正如Attila所說:
如您所見,無論我們做什么,都會遭受其他損失; 重載方法的選擇在Java和JS類型系統之間處于緊要關頭,并且即使邏輯上的微小變化也非常敏感。
真正! 但是重載方法的選擇不僅對很小的變化非常敏感。 也可以將Nashorn與Java互操作性一起使用! 作為API設計師,多年來,我已經習慣了語義版本控制 ,并且在保持API源代碼兼容,行為兼容(如果可能)以及很大程度上與二進制兼容的情況下 ,要遵循許多細微的規則。
當您的客戶使用Nashorn時,就不用管它了。 他們是自己的。 Java API中新引入的重載可能會嚴重破壞Nashorn客戶端。 但是話又說回來,那是JavaScript,一種在運行時告訴您的語言:
['10','10','10','10'].map(parseInt)…產量
[10, NaN, 2, 3]…以及哪里
++[[]][+[]]+[+[]] === "10"產生真實的! ( 這里的資料 )
有關JavaScript的更多信息, 請訪問此入門教程 。
翻譯自: https://www.javacodegeeks.com/2014/09/how-nashorn-impacts-api-evolution-on-a-new-level.html
總結
以上是生活随笔為你收集整理的Nashorn如何在新层面上影响API的发展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 捷波朗 Elite10 降噪蓝牙耳机上架
- 下一篇: 工资12000能打入二类卡么?