一個Java方法可以使用多少個參數(shù)

這篇文章主要介紹“一個Java方法可以使用多少個參數(shù)”,在日常操作中,相信很多人在一個Java方法可以使用多少個參數(shù)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”一個Java方法可以使用多少個參數(shù)”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)公司長期為上1000+客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為儀征企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計,儀征網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

我最近給我fork的項目QuickTheories增加了一個接口:

@FunctionalInterface public interface QuadFunction<A, B, C, D, E> {     E apply(A a, B b, C c, D d); }

這讓非常好奇一個方法能夠有多少個類型參數(shù)呢?據(jù)我所知,Java的語言規(guī)范并沒有提到這個問題。1

關(guān)于在實現(xiàn)上這個閾值的定義,我有兩個猜測:

編譯器會強制一個可預(yù)測的閾值,例如255或者65535。

由于實現(xiàn)細(xì)節(jié)的原因,編譯器的異常處理會施加意想不到的限制。

我不想通過我薄弱的C++技能來測試源代碼,所以我決定直接來測試編譯器2。我寫了一個Python腳本,通過二分法找到一個會觸發(fā)錯誤的最小值。完整的代碼請見連接Github  Repo。

最直接的辦法就是生成方法。幸運的是,我們不必使用任何已有的類型參數(shù),只需要按照

def write_type_plain(count):     with open('Test.java', 'w') as f:         f.write("public class Test {\n")         f.write("public <")         for i in range(count):             if (i > 0):                 f.write(", ")             f.write("A" + str(i + 1))         f.write("> void testMethod() {}")         f.write("}")

運行這個二分法的代碼會有如下輸出:

>>> error: UTF8 representation for string "<A1:Ljava/lang/Objec..." is too long for the constant pool  >>> largest type: 2776

這個錯誤讓人有點費解,但是從事后來看還是可以理解的。編譯器生成的類文件包含多個字符串,包括每個方法的方法簽名。這些字符串保存在常量池內(nèi),而常量池的內(nèi)容有最大65535字節(jié)數(shù)的限制,這個是JVM的所定義的。

所以,我之前的猜測都不是完全的正確。類型參數(shù)的最大個數(shù)是一個意料之外的值,而不是一個確定值。但是,編譯器的實現(xiàn)本身并不是導(dǎo)致錯誤的原因3。相反,是JVM類文件的格式要求限制了類型參數(shù)可使用的數(shù)量。其實JVM對泛型本身一無所知。

這同時也表示類型參數(shù)的最大個數(shù)取決于你寫的方法代碼4。我嘗試用另外一種類型參數(shù)的編碼方案(先前鏈接文中的write_type_compact),使用全部合法的ASCII字符。這個實現(xiàn)是有點繁瑣的,因為字符0-9是合法的,但不能作為標(biāo)識符的首字母,并且Java關(guān)鍵字也不能作為類型參數(shù)。我僅僅將if和do替換為等長的UTF-8字符。采用這種更緊湊的編碼方案讓類型參數(shù)的個數(shù)從2776提升到了3123。

還是有一些不太方便的地方,例如_A是一個合法的Java標(biāo)識符,但是_不是。我的編碼在不使用_作為首字幕的情況下,最高生成了3392個2字節(jié)的類型參數(shù)。所以我覺得不用考慮_作為首字母的情況了。

另外一個技巧

通過反編譯類文件,我觀察到65536個字符中大部分都不是我生成的類型參數(shù),而是重復(fù)的字符串Ljava/lang/Object;。這是因為類型參數(shù)沒有包含額外的信息,所以類文件將其視為Object的繼承,并將它們編入方法簽名內(nèi)。我通過修改我的生成器來優(yōu)化這個問題。

循環(huán)的關(guān)鍵代碼修改為:

s = type_var(i) f.write(s) if (s != 'A'):     f.write(" extends A")

除開一個實例之外,所有的類型參數(shù)都從繼承java/lang/Object改為繼承A。這個修改將類型參數(shù)的數(shù)量提升到9851個。

類型參數(shù)的數(shù)量提升了非常多,而我所使用的編碼方法還可以繼續(xù)改進。例如使用非ASCII unicode標(biāo)識符,不過我已經(jīng)比較滿意現(xiàn)在的效果了。

這些都不重要

在實際情況中是不太可能達(dá)到上述數(shù)量限制的。代碼生成時可能會達(dá)到語言或者編譯器的某些極限,就算罕見的遇到了生成上百個類型參數(shù)的情況,那距離幾千個的限制仍然還相距很遠(yuǎn)。

盡管如此,如果我是規(guī)則的制定者,我將不允許任何類或者方法使用超過255個類型參數(shù)的情況。即使只影響了百萬分之一的程序,有明確的限制會更好。

  1. &sect;4.4, &sect;8.1.2, &sect;9.1.2, &sect;8.4.4, &sect;8.8.4  這些章節(jié)都和方法或者類的類型參數(shù)有關(guān),但是都沒有指明允許有多少個類型參數(shù)。

  2. 當(dāng)我寫這段話時,我想起了Hotspot是C++寫的,javac是Java寫的。就算這樣我依然會選擇做代碼實驗,而不是閱讀代碼。閱讀別人代碼是種煎熬

  3. 逗號之后的空格不會影響,因為編譯器會規(guī)范化它的輸出。

  4. 這也表示與我使用哪個JVM無關(guān)。為了完整性,我在Fedora 29上使用了1.8.0_191-b13版本的OpenJdk。

到此,關(guān)于“一個Java方法可以使用多少個參數(shù)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

網(wǎng)站題目:一個Java方法可以使用多少個參數(shù)
瀏覽路徑:http://muchs.cn/article26/pdghjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司網(wǎng)站策劃、企業(yè)網(wǎng)站制作、響應(yīng)式網(wǎng)站、外貿(mào)建站、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名