最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java方法能定義多少個(gè)參數(shù)你知道嗎

 更新時(shí)間:2018年09月09日 10:52:07   作者:汪先生  
這篇文章主要給大家介紹了關(guān)于Java方法能定義多少個(gè)參數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

如何定義 Java 中的方法

所謂方法,就是用來(lái)解決一類問(wèn)題的代碼的有序組合,是一個(gè)功能模塊。

一般情況下,定義一個(gè)方法的語(yǔ)法是:

其中:

1、 訪問(wèn)修飾符:方法允許被訪問(wèn)的權(quán)限范圍, 可以是 public、protected、private 甚至可以省略 ,其中 public 表示該方法可以被其他任何代碼調(diào)用,其他幾種修飾符的使用在后面章節(jié)中會(huì)詳細(xì)講解滴

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

3、 方法名:定義的方法的名字,必須使用合法的標(biāo)識(shí)符

4、 參數(shù)列表:傳遞給方法的參數(shù)列表,參數(shù)可以有多個(gè),多個(gè)參數(shù)間以逗號(hào)隔開,每個(gè)參數(shù)由參數(shù)類型和參數(shù)名組成,以空格隔開

本文將詳細(xì)的介紹Java方法能定義多少個(gè)參數(shù)的相關(guān)內(nèi)容,下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧

一:為什么研究這么無(wú)聊的問(wèn)題

這兩天在讀一本老書《Orange'S 一個(gè)操作系統(tǒng)的實(shí)現(xiàn)》,把丟了很長(zhǎng)時(shí)間沒研究的操作系統(tǒng)又重新拾起來(lái)了,在第三章講解“保護(hù)模式”時(shí),作者提到了調(diào)用門描述符中的Param Count只有5位,也就是說(shuō),最多只支持32個(gè)參數(shù),這本來(lái)只是一個(gè)不是特別重要的細(xì)節(jié),但是卻勾起了我的思索:在JVM中,一個(gè)Java方法,最多能定義多少參數(shù)呢?我知道這是一個(gè)很無(wú)聊的問(wèn)題,即使能定義一萬(wàn)個(gè),十萬(wàn)個(gè),誰(shuí)又會(huì)真的去這么做呢。但是作為一個(gè)Coder,最重要的不就是好奇心嗎,沒有好奇心,和一條咸魚又有什么區(qū)別呢?

二:實(shí)地考察

這種問(wèn)題,第一步當(dāng)然就是看看JVM中關(guān)于方法的定義,這里以openJDK10中的HotSpot為例。

在ConstMethod中,代表參數(shù)數(shù)量的字段為_size_of_parameters。

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

_size_of_parameters的類型為u2,在JVM中,u2為2個(gè)字節(jié)長(zhǎng),那么理論上來(lái)說(shuō),HotSpot支持的方法最大參數(shù)數(shù)量為2^16 - 1,即65535。

這個(gè)答案究竟是否正確呢?實(shí)踐出真知!

當(dāng)然我不會(huì)傻到真的去一個(gè)個(gè)定義65535個(gè)參數(shù),那我豈不成了“數(shù)一億粒米”的幼兒園老師了?Coder就得按照Coder的辦法:

 public static void main(String[] args) {
 for (int i = 0; i < 65535; i++) {
  System.out.print("int a" + i + ",");
 }
 }

完美解放了生產(chǎn)力😂 。

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

居然不是65535?那應(yīng)該是多少呢?難道是一個(gè)字節(jié)長(zhǎng)?廢話不多說(shuō),我立即來(lái)實(shí)驗(yàn)了下255個(gè)參數(shù),編譯通過(guò),再試了一下256,和65535時(shí)一樣報(bào)錯(cuò)。那么結(jié)果很明顯了,Java方法最多可以定義255個(gè)參數(shù)。

我查看了下Javac源碼,在生成方法的字節(jié)碼時(shí),有方法參數(shù)數(shù)量限制判斷:

 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中明明是用兩個(gè)字節(jié)長(zhǎng)來(lái)定義的方法參數(shù)數(shù)量,莫非只是Javac在編譯過(guò)程中做了限制?只要能成功編譯出一個(gè)有256個(gè)參數(shù)的java方法,在虛擬機(jī)中一試便知,但是怎么才能繞過(guò)Javac呢?

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

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

二:利用字節(jié)碼修改工具,硬改字節(jié)碼,加上一個(gè)擁有256個(gè)參數(shù)的方法。

第一種方法看似簡(jiǎn)單,但是其實(shí)從openJDK中提取出來(lái)的Javac項(xiàng)目不能直接run,需要很多配置,而且源碼依賴了很多jdk中的不可見類,操作起來(lái)很麻煩。所以這里我采用了第二種方法,工具選用的是老朋友javassist。

其實(shí)javassist使用起來(lái)很簡(jiǎn)單,這里我只需要對(duì)一個(gè)已有的class文件加上一個(gè)新方法即可:

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

以上就通過(guò)javassist成功的給Test.class 文件加上了一個(gè)擁有256個(gè)參數(shù)的方法testMax()。現(xiàn)在讓我們運(yùn)行下Test.class試試:

 java com.wangxiandeng.test.Test

沒想到這次雖然瞞過(guò)了編譯器,卻沒有過(guò)的了虛擬機(jī)這一關(guān),運(yùn)行直接報(bào)錯(cuò)了:

錯(cuò)誤: 加載主類 com.wangxiandeng.test.Test 時(shí)出現(xiàn) LinkageError
        java.lang.ClassFormatError: Too many arguments in method signature in class file com/wangxiandeng/test/Test

看樣子Java不僅僅在編譯期會(huì)對(duì)方法參數(shù)數(shù)量做限制,在虛擬機(jī)運(yùn)行期間同樣會(huì)干這件事。
本著一查到底的精神,我在HotSpot源碼中搜索了下上面報(bào)的錯(cuò)誤,找到了虛擬機(jī)檢查參數(shù)數(shù)量的地方:

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

可見虛擬機(jī)在解析class文件中的方法時(shí),會(huì)判斷參數(shù)數(shù)量args_size是否大于MAX_ARGS_SIZE,如果大于則就會(huì)報(bào)錯(cuò)了。MAX_ARGS_SIZE為255。

這里有一點(diǎn)需要注意,在計(jì)算args_size時(shí),有判斷方法是否為static方法,如果不是static方法,則會(huì)在方法原有參數(shù)數(shù)量上再加一,這是因?yàn)榉莝tatic方法會(huì)添加一個(gè)默認(rèn)參數(shù)到參數(shù)列表首位:方法的真正執(zhí)行者,即方法所屬類的實(shí)例對(duì)象。

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

有人可能要問(wèn),如果我定義的方法參數(shù)是變長(zhǎng)參數(shù)呢?還有這種限制嗎?這當(dāng)然是沒有的,因?yàn)樽兂蓞?shù)的本質(zhì)其實(shí)就是傳遞一個(gè)數(shù)組,你傳再多的參數(shù),編譯后其實(shí)都只是一個(gè)數(shù)組而已。

一切都結(jié)束了

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

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Spring中的retry重試組件詳解

    Spring中的retry重試組件詳解

    這篇文章主要介紹了Spring中的retry重試組件詳解,Retry重試組件是一個(gè)處理重試邏輯的工具,可以在出現(xiàn)異常或失敗情況下自動(dòng)進(jìn)行重試操作,從而提高程序的穩(wěn)定性和可靠性,需要的朋友可以參考下
    2023-10-10
  • SpringBoot淺析緩存機(jī)制之Ehcache?2.x應(yīng)用

    SpringBoot淺析緩存機(jī)制之Ehcache?2.x應(yīng)用

    EhCache?是一個(gè)純Java的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn)。它是Hibernate中的默認(rèn)緩存框架。Ehcache已經(jīng)發(fā)布了3.1版本。但是本文的講解基于2.x版本
    2022-08-08
  • SpringBoot使用讀寫鎖解決緩存一致性的問(wèn)題

    SpringBoot使用讀寫鎖解決緩存一致性的問(wèn)題

    本文主要介紹了SpringBoot使用讀寫鎖解決緩存一致性的問(wèn)題,通過(guò)在緩存類中維護(hù)一個(gè)讀寫鎖,可以在讀多寫少的場(chǎng)景下提高并發(fā)訪問(wèn)效率,感興趣的可以了解一下
    2025-03-03
  • Spring中@Scheduled注解的參數(shù)詳解

    Spring中@Scheduled注解的參數(shù)詳解

    這篇文章主要介紹了Spring中@Scheduled注解的參數(shù)詳解,@Scheduled注解的使用這里不詳細(xì)說(shuō)明,@Scheduled注解有幾個(gè)參數(shù)需要說(shuō)明一下,直接對(duì)8個(gè)參數(shù)進(jìn)行講解,需要的朋友可以參考下
    2023-11-11
  • Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁(yè))

    Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁(yè))

    這篇文章主要介紹了Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁(yè)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 關(guān)于java后端的詳解

    關(guān)于java后端的詳解

    在本篇文章里小編給各位分享的是關(guān)于java后端的知識(shí)點(diǎn)詳解,學(xué)習(xí)java的朋友們可以參考下。
    2019-08-08
  • 詳解SpringMVC 基礎(chǔ)教程 簡(jiǎn)單入門實(shí)例

    詳解SpringMVC 基礎(chǔ)教程 簡(jiǎn)單入門實(shí)例

    這篇文章主要介紹了詳解SpringMVC 基礎(chǔ)教程 簡(jiǎn)單入門實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • MyBatis 核心配置文件及映射文件詳解

    MyBatis 核心配置文件及映射文件詳解

    MyBatis是支持定制化SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的持久層框架,本文重點(diǎn)介紹MyBatis 核心配置文件及映射文件,需要的朋友可以參考下
    2023-01-01
  • 三行Java代碼實(shí)現(xiàn)計(jì)算多邊形的幾何中心點(diǎn)

    三行Java代碼實(shí)現(xiàn)計(jì)算多邊形的幾何中心點(diǎn)

    因?yàn)楣ぷ餍枰?jì)算采煤機(jī)工作面的中心點(diǎn),如果套用數(shù)學(xué)的計(jì)算公式,用java去實(shí)現(xiàn),太麻煩了。本文將利用java幾何計(jì)算的工具包,幾行代碼就能求出多變形的中心,簡(jiǎn)直yyds!還不快跟隨小編一起學(xué)起來(lái)
    2022-10-10
  • 詳解Java的Spring框架中的注解的用法

    詳解Java的Spring框架中的注解的用法

    這篇文章主要介紹了Java的Spring框架中的注解的用法,包括對(duì)Java bean的定義的作用介紹,需要的朋友可以參考下
    2015-11-11

最新評(píng)論

白玉县| 镇远县| 黔西| 怀化市| 甘洛县| 石柱| 永德县| 盘锦市| 通城县| 阜平县| 关岭| 宁明县| 綦江县| 宁海县| 枞阳县| 邯郸县| 察隅县| 苗栗市| 竹山县| 隆尧县| 云南省| 砀山县| 白沙| 潮安县| 涞水县| 济源市| 基隆市| 永定县| 电白县| 黄大仙区| 长泰县| 汾西县| 新干县| 涪陵区| 凌云县| 松桃| 蚌埠市| 兴义市| 台中县| 顺昌县| 云林县|