国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看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

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久久久国产一区 | 免费观看黄色av网站 | 国产精品亚洲第一区在线暖暖韩国 | 国产精品极品美女在线观看免费 | 欧美日本韩国一区二区三区 | 亚洲国产成人精品久久久国产成人一区 | 91久久精品国产91久久性色tv | www.国产| 久久h| 国产精品综合一区二区 | 国产成人精品久久二区二区91 | 久久久国产一区二区 | 日韩视频免费 | 国内精品一区二区 | 亚洲人免费视频 | 日韩精品一区二区三区中文在线 | 日韩精品一区二区三区在线播放 | 国产剧情一区 | 亚洲高清日本 | 精久久 | 婷婷五月情 | 午夜电影福利 | 在线看片你懂得 | 欧美日韩高清 | 久久国产精品一区 | 黄色美女网站视频 | 99re在线精品 | 青青草综合| 综合久久久久 | 日本黄色一区 | 久久99视频这里只有精品 | 红桃av一区二区 | 亚洲视频在线免费观看 | 国产精品一区二区免费 | 黄色网页在线观看 | 国产精品日本一区二区不卡视频 | 欧美日韩亚洲国产 | 视频一区二区在线观看 | 国产成人久久精品一区二区三区 | 欧美日韩成人精品 | 国产精品99久久免费观看 |