成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一個Java方法能使用多少個參數(shù)?

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

 [[336266]]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

另外一個技巧

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

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

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

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

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

這些都不重要

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

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

  1. §4.4, §8.1.2, §9.1.2, §8.4.4, §8.8.4 這些章節(jié)都和方法或者類的類型參數(shù)有關,但是都沒有指明允許有多少個類型參數(shù)。
  2. 當我寫這段話時,我想起了Hotspot是C++寫的,javac是Java寫的。就算這樣我依然會選擇做代碼實驗,而不是閱讀代碼。閱讀別人代碼是種煎熬
  3. 逗號之后的空格不會影響,因為編譯器會規(guī)范化它的輸出。
  4. 這也表示與我使用哪個JVM無關。為了完整性,我在Fedora 29上使用了1.8.0_191-b13版本的OpenJdk。

本文作者:justinblank, 翻譯:Lephix

原文鏈接:

https://justinblank.com/experiments/howmanytypeparameterscanajavamethodhave.html

版權歸作者所有,轉載請注明作者、原文、譯者等出處信息

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2023-09-26 16:44:14

光模塊

2023-09-04 08:08:59

2022-03-08 22:21:55

網絡包隊列網卡

2019-12-20 09:31:23

TCPHTTP瀏覽器

2019-05-29 15:17:43

TCPHTTPSSL

2019-07-09 06:13:09

TCPHTTP網絡協(xié)議

2020-11-11 10:10:20

調用函數(shù)參數(shù)變量

2019-01-08 09:23:16

Java字符串編碼

2021-03-29 08:47:24

線程面試官線程池

2019-01-02 16:31:33

程序員技術互聯(lián)網

2019-11-14 16:05:29

TCPHTTP前端

2020-06-16 11:00:40

線程Java代碼

2019-09-30 08:50:51

Linux發(fā)行版內核

2024-11-06 08:49:46

2018-03-09 12:14:36

Linux服務器負載

2020-12-28 05:54:37

構造builder模式

2021-03-11 08:32:58

參數(shù)模式構造

2023-08-28 07:26:01

2024-03-18 08:21:06

TCPUDP協(xié)議

2023-06-25 10:04:50

自動駕駛智能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 五月天国产视频 | 国产丝袜一区二区三区免费视频 | 精品国产欧美一区二区 | 日韩伦理一区二区三区 | 国产精品亚洲一区 | 成人在线播放网址 | 亚洲一区二区精品视频 | 五月激情婷婷在线 | 精品久久久久久一区二区 | 日韩成人在线播放 | 成人av免费网站 | 亚洲精品99 | 久久久精品一区二区三区四季av | 精品av天堂毛片久久久借种 | 日本a∨精品中文字幕在线 亚洲91视频 | 欧美日韩亚洲一区 | 成人国产在线视频 | 免费h在线 | 日韩国产中文字幕 | 一级片av| 日韩精品视频中文字幕 | 日韩色在线 | 一区二区在线 | 古装人性做爰av网站 | 久久精品亚洲欧美日韩精品中文字幕 | 欧美日韩亚洲在线 | 久久鲁视频| 亚洲一区二区中文字幕在线观看 | 欧美一区二区二区 | 激情视频中文字幕 | 日韩午夜场 | www.亚洲| 男人的天堂视频网站 | 国产美女在线免费观看 | 欧美精品在线观看 | 国产精品一区二区久久久久 | 亚洲欧美日韩精品久久亚洲区 | 亚洲免费观看视频网站 | 免费一看一级毛片 | 久久久精品一区 | 一区二区在线 |