激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java方法能定義多少個參數你知道嗎

Java方法能定義多少個參數你知道嗎

2021-05-30 16:05汪先生 Java教程

這篇文章主要給大家介紹了關于Java方法能定義多少個參數的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用java具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

如何定義 java 中的方法

所謂方法,就是用來解決一類問題的代碼的有序組合,是一個功能模塊。

一般情況下,定義一個方法的語法是:

Java方法能定義多少個參數你知道嗎

其中:

1、 訪問修飾符:方法允許被訪問的權限范圍, 可以是 public、protected、private 甚至可以省略 ,其中 public 表示該方法可以被其他任何代碼調用,其他幾種修飾符的使用在后面章節中會詳細講解滴

2、 返回值類型:方法返回值的類型,如果方法不返回任何值,則返回值類型指定為 void ;如果方法具有返回值,則需要指定返回值的類型,并且在方法體中使用 return 語句返回值

3、 方法名:定義的方法的名字,必須使用合法的標識符

4、 參數列表:傳遞給方法的參數列表,參數可以有多個,多個參數間以逗號隔開,每個參數由參數類型和參數名組成,以空格隔開

本文將詳細的介紹java方法能定義多少個參數的相關內容,下面話不多說了,來一起看看詳細的介紹吧

一:為什么研究這么無聊的問題

這兩天在讀一本老書《orange's 一個操作系統的實現》,把丟了很長時間沒研究的操作系統又重新拾起來了,在第三章講解“保護模式”時,作者提到了調用門描述符中的param count只有5位,也就是說,最多只支持32個參數,這本來只是一個不是特別重要的細節,但是卻勾起了我的思索:在jvm中,一個java方法,最多能定義多少參數呢?我知道這是一個很無聊的問題,即使能定義一萬個,十萬個,誰又會真的去這么做呢。但是作為一個coder,最重要的不就是好奇心嗎,沒有好奇心,和一條咸魚又有什么區別呢?

二:實地考察

這種問題,第一步當然就是看看jvm中關于方法的定義,這里以openjdk10中的hotspot為例。

在constmethod中,代表參數數量的字段為_size_of_parameters。

?
1
u2  _size_of_parameters;  // size of the parameter block (receiver + arguments) in words

_size_of_parameters的類型為u2,在jvm中,u2為2個字節長,那么理論上來說,hotspot支持的方法最大參數數量為2^16 - 1,即65535。

這個答案究竟是否正確呢?實踐出真知!

當然我不會傻到真的去一個個定義65535個參數,那我豈不成了“數一億粒米”的幼兒園老師了?coder就得按照coder的辦法:

?
1
2
3
4
5
public static void main(string[] args) {
for (int i = 0; i < 65535; i++) {
 system.out.print("int a" + i + ",");
}
}

完美解放了生產力。

生成完參數列表,定義好方法,當我滿懷信心的開始編譯時,編譯器給了我狠狠一刀:

Java方法能定義多少個參數你知道嗎

居然不是65535?那應該是多少呢?難道是一個字節長?廢話不多說,我立即來實驗了下255個參數,編譯通過,再試了一下256,和65535時一樣報錯。那么結果很明顯了,java方法最多可以定義255個參數。

我查看了下javac源碼,在生成方法的字節碼時,有方法參數數量限制判斷:

?
1
2
3
4
if (code.width(types.erasure(env.enclmethod.sym.type).getparametertypes()) + extras > classfile.max_parameters) {
log.error(tree.pos(), "limit.parameters");
nerrs++;
}

其中 classfile.max_parameters = 255。

事情到這里我很不甘心,hotspot中明明是用兩個字節長來定義的方法參數數量,莫非只是javac在編譯過程中做了限制?只要能成功編譯出一個有256個參數的java方法,在虛擬機中一試便知,但是怎么才能繞過javac呢?

我覺得主要有以下兩種辦法:

一:修改javac源碼,干掉以上參數限制這一段代碼,再重新編譯;

二:利用字節碼修改工具,硬改字節碼,加上一個擁有256個參數的方法。

第一種方法看似簡單,但是其實從openjdk中提取出來的javac項目不能直接run,需要很多配置,而且源碼依賴了很多jdk中的不可見類,操作起來很麻煩。所以這里我采用了第二種方法,工具選用的是老朋友javassist。

其實javassist使用起來很簡單,這里我只需要對一個已有的class文件加上一個新方法即可:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
try {
 stringbuilder sb = new stringbuilder();
 
 sb.append("public static void testmax(");
 
 for (int i = 0; i < 256; i++) {
 sb.append("int a" + i);
 if(i < 255) {
  sb.append(",");
 }
 }
 sb.append("){}");
 
 classpool cpool = new classpool(true);
 cpool.insertclasspath("/users/wanginbeijing/documents/myprogramings/java/mine/test/src");
 ctclass cclass = cpool.get("com.wangxiandeng.test.test");
 ctmethod newmethod = ctnewmethod.make(sb.tostring(), cclass);
 cclass.addmethod(newmethod);
 cclass.writefile("/users/wanginbeijing/documents/myprogramings/java/mine/test/src");
} catch (notfoundexception e) {
 e.printstacktrace();
} catch (cannotcompileexception e) {
 e.printstacktrace();
} catch (
 ioexception e) {
 e.printstacktrace();
}

以上就通過javassist成功的給test.class 文件加上了一個擁有256個參數的方法testmax()。現在讓我們運行下test.class試試:

?
1
java com.wangxiandeng.test.test

沒想到這次雖然瞞過了編譯器,卻沒有過的了虛擬機這一關,運行直接報錯了:

錯誤: 加載主類 com.wangxiandeng.test.test 時出現 linkageerror
        java.lang.classformaterror: too many arguments in method signature in class file com/wangxiandeng/test/test

看樣子java不僅僅在編譯期會對方法參數數量做限制,在虛擬機運行期間同樣會干這件事。
本著一查到底的精神,我在hotspot源碼中搜索了下上面報的錯誤,找到了虛擬機檢查參數數量的地方:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
method* classfileparser::parse_method(const classfilestream* const cfs,
     bool is_interface,
     const constantpool* cp,
     accessflags* const promoted_flags,
     traps) {
 ......
 if (_need_verify) {
  args_size = ((flags & jvm_acc_static) ? 0 : 1) +verify_legal_method_signature(name, signature, check_null);
 
  if (args_size > max_args_size) {
   classfile_parse_error("too many arguments in method signature in class file %s", check_null);
  }
 }
 ......
}

可見虛擬機在解析class文件中的方法時,會判斷參數數量args_size是否大于max_args_size,如果大于則就會報錯了。max_args_size為255。

這里有一點需要注意,在計算args_size時,有判斷方法是否為static方法,如果不是static方法,則會在方法原有參數數量上再加一,這是因為非static方法會添加一個默認參數到參數列表首位:方法的真正執行者,即方法所屬類的實例對象。

事情到這里總算大概明白了,java static方法的參數最多只能有255個,非static方法最多只能有254個。雖然遠不及我剛開始推測的65535個,但是這也完全夠用了,畢竟你敢在你的項目里定義一個255個參數的方法而保證不被人打死嗎。

有人可能要問,如果我定義的方法參數是變長參數呢?還有這種限制嗎?這當然是沒有的,因為變成參數的本質其實就是傳遞一個數組,你傳再多的參數,編譯后其實都只是一個數組而已。

一切都結束了

嗯,做完實驗,寫完文章,我總算把這件事搞明白了,女朋友早已在呼呼大睡,好像我確實很無聊,好像我確實還是一條咸魚。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://zhuanlan.zhihu.com/p/44086976

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 一级外国毛片 | 九九午夜视频 | 一起草av在线 | 羞羞视频免费网站 | 成人午夜激情视频 | 欧美日韩亚洲成人 | 中国av免费观看 | 亚洲第一黄色网 | 国产精品片一区二区三区 | 少妇一级淫片免费看 | 午夜视频在线观看免费视频 | 91美女视频在线 | 国产一区二区不卡视频 | 高清中文字幕在线 | 91亚洲精品一区二区福利 | 亚洲免费视 | 2023av在线视频| 国产免费中文字幕 | 日韩视频在线观看免费 | 精品视频一区二区三区四区 | 久久性生活免费视频 | 大奶一级片 | 日韩黄色av | 国产精品男女 | 久久国产精品久久久久久久久久 | 99国产精成人午夜视频一区二区 | 中文字幕爱爱视频 | 91免费高清视频 | 久久最新视频 | 国产呻吟 | 一级黄色a视频 | 久久久久九九九女人毛片 | 91精品国产一区二区三区动漫 | 欧美a∨一区二区三区久久黄 | 亚洲影视中文字幕 | 日本不卡一二三区 | 久久成人精品视频 | 在线看免费观看日本 | 成人一级免费视频 | 污片在线观看视频 | 国产精品99久久久久久久vr |