91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java方法可以定義多少個參數

發布時間:2021-06-11 14:49:19 來源:億速云 閱讀:256 作者:Leah 欄目:編程語言

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。

 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的辦法:

 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源碼,在生成方法的字節碼時,有方法參數數量限制判斷:

 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文件加上一個新方法即可:

 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試試:

 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源碼中搜索了下上面報的錯誤,找到了虛擬機檢查參數數量的地方:

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);
  }
 }
 ......
}

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙井市| 汝城县| 清丰县| 万山特区| 绿春县| 盐津县| 昭平县| 靖江市| 西盟| 清丰县| 同德县| 肇东市| 汉阴县| 武城县| 丹寨县| 尚志市| 荥阳市| 开平市| 扶风县| 金平| 明星| 抚远县| 客服| 新闻| 德令哈市| 读书| 永靖县| 英超| 丰城市| 沾化县| 车险| 马龙县| 文成县| 丰台区| 宣恩县| 交口县| 息烽县| 寿阳县| 惠来县| 镇沅| 福清市|