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