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

java?數(shù)組越界判斷和獲取數(shù)組長度的實(shí)現(xiàn)方式

 更新時(shí)間:2021年12月22日 10:07:33   投稿:jingxian  
這篇文章主要介紹了java?數(shù)組越界判斷和獲取數(shù)組長度的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1. 背景介紹

java中的數(shù)組比c語言中的數(shù)組,多了兩個(gè)很重要的功能

  • 當(dāng)索引越界時(shí), 會(huì)自動(dòng)拋出ArrayIndexOutOfBoundsException, 避免一錯(cuò)再錯(cuò)
  • 另一個(gè)很重要的方法是獲取數(shù)組長度

這兩個(gè)功能都不是通過java代碼層面實(shí)現(xiàn)的, 而是在jvm中通過c++來實(shí)現(xiàn)的. 本文就針對這連個(gè)點(diǎn)來一探究竟

2. 原始java代碼

public class TestArrayIndexOutOfBoundsException {
    public static void main(String[] args) {
        int[] is = new int[2];
        int x = is[5];
        System.out.println(x);
        int len = is.length;
        System.out.println(len);
    }
}

3. java代碼對應(yīng)的反編譯字節(jié)碼

 0 iconst_2
 1 newarray 10 (int) // 創(chuàng)建長度為2的int型數(shù)組
 3 astore_1 // 將數(shù)組is存儲(chǔ)到local stack的slot1中
 4 aload_1 // 將數(shù)組is壓入操作數(shù)棧
 5 iconst_5 // 將常量5壓入操作數(shù)棧
 6 iaload // 這個(gè)指令就是通過數(shù)組索引獲取元素, is[5]
 7 istore_2
 8 getstatic #2 <java/lang/System.out>
11 iload_2
12 invokevirtual #3 <java/io/PrintStream.println>
15 aload_1 // 將數(shù)組is壓入操作數(shù)棧
16 arraylength // 獲取is數(shù)組的長度
17 istore_3
18 getstatic #2 <java/lang/System.out>
21 iload_3
22 invokevirtual #3 <java/io/PrintStream.println>
25 return

4. jvm實(shí)現(xiàn)分析

4.1 獲取數(shù)組長度arraylength指令核心代碼分析

// hotspot\src\share\vm\interpreter\bytecodeInterpreter.cpp
void
BytecodeInterpreter::run(interpreterState istate) {
// 省略無關(guān)代碼
 CASE(_arraylength):
 {
  // java中的對象實(shí)例, 對應(yīng)的c++實(shí)例就是arrayOopDesc
     arrayOop ary = (arrayOop) STACK_OBJECT(-1);
     CHECK_NULL(ary);
     SET_STACK_INT(ary->length(), -1); // 就是通過ary->length()這個(gè)方法來獲取數(shù)組長度
     UPDATE_PC_AND_CONTINUE(1);
 }
}
// 省略無關(guān)代碼

4.2 獲取數(shù)組元素iaload指令分析

// hotspot\src\share\vm\interpreter\bytecodeInterpreter.cpp
void
BytecodeInterpreter::run(interpreterState istate) {
// 省略無關(guān)代碼
 #define ARRAY_INTRO(arrayOff)                                                  \
       arrayOop arrObj = (arrayOop)STACK_OBJECT(arrayOff);                      \ // 從局部變量表中獲取數(shù)組對象is
       jint     index  = STACK_INT(arrayOff + 1);                               \ // 從局部變量表中獲取索引5
       char message[jintAsStringSize];                                          \
       CHECK_NULL(arrObj);                                                      \
       if ((uint32_t)index >= (uint32_t)arrObj->length()) {                     \ // 判斷索引是否大于或等于數(shù)組長度
           sprintf(message, "%d", index);                                       \
           VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \ // 如果越界, 則拋出ArrayIndexOutOfBoundsException異常
                         message);                                              \
       }
// 省略無關(guān)代碼
 #define ARRAY_LOADTO32(T, T2, format, stackRes, extra)                                \
       {                                                                               \
           ARRAY_INTRO(-2);                                                            \ // 獲取數(shù)組所在的地址
           (void)extra;                                                                \
           SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \ // 根據(jù)數(shù)組所在地址,加上索引計(jì)算的偏移地址, 獲得數(shù)組指定元素
                            -2);                                                       \
           UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);                                      \
       }
// 省略無關(guān)代碼
 CASE(_iaload): // 此處對應(yīng)的就是iaload指令的具體實(shí)現(xiàn)
          ARRAY_LOADTO32(T_INT, jint,   "%d",   STACK_INT, 0);
}
// 省略無關(guān)代碼

通過上面代碼的分析, 可以jvm是通過(uint32_t)index >= (uint32_t)arrObj->length()來判斷數(shù)組越界

5. 小結(jié)一下

java中的數(shù)組和c語言數(shù)組差異很大, c語言中的數(shù)組更原始,直接和內(nèi)存對應(yīng)。而java中的數(shù)組類型其實(shí)是經(jīng)過了arrayOopDesc的封裝,因而能獲得更豐富的信息,做更多語言層面的檢查。

java 數(shù)組越界問題

Java中數(shù)組初始化和OC其實(shí)是一樣的,分為動(dòng)態(tài)初始化和靜態(tài)初始化,

  • 動(dòng)態(tài)初始化:指定長度,由系統(tǒng)給出初始化值
  • 靜態(tài)初始化:給出初始化值,由系統(tǒng)給出長度

在我們使用數(shù)組時(shí)最容易出現(xiàn)的就是數(shù)組越界問題,好了,下面來演示一下

int [][] array = {{1,2,3},{1,4}};
        System.out.println(array[1][2]);

這是一個(gè)二維數(shù)組,很明顯,數(shù)組越界了,控制臺(tái)中會(huì)打印如下信息:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2

at demo.Array.main(Array.java:31)

很準(zhǔn)確的定位到31行

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • idea導(dǎo)入項(xiàng)目不顯示maven側(cè)邊欄的問題及解決方法

    idea導(dǎo)入項(xiàng)目不顯示maven側(cè)邊欄的問題及解決方法

    這篇文章主要介紹了idea導(dǎo)入項(xiàng)目不顯示maven側(cè)邊欄的問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Project?Reactor?響應(yīng)式范式編程

    Project?Reactor?響應(yīng)式范式編程

    這篇文章主要為大家介紹了Project?Reactor?響應(yīng)式范式編程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java讀取properties文件內(nèi)容的幾種方式詳解

    Java讀取properties文件內(nèi)容的幾種方式詳解

    這篇文章主要介紹了Java讀取properties文件內(nèi)容的幾種方式詳解,讀取properties配置文件在實(shí)際的開發(fā)中使用的很多,本文來介紹常用的幾種實(shí)現(xiàn)方式,需要的朋友可以參考下
    2023-11-11
  • 聊聊@RequestMapping和@GetMapping @PostMapping的區(qū)別

    聊聊@RequestMapping和@GetMapping @PostMapping的區(qū)別

    這篇文章主要介紹了@RequestMapping和@GetMapping及@PostMapping的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java防止頻繁請求、重復(fù)提交的操作代碼(后端防抖操作)

    Java防止頻繁請求、重復(fù)提交的操作代碼(后端防抖操作)

    在客戶端網(wǎng)絡(luò)慢或者服務(wù)器響應(yīng)慢時(shí),用戶有時(shí)是會(huì)頻繁刷新頁面或重復(fù)提交表單的,這樣是會(huì)給服務(wù)器造成不小的負(fù)擔(dān)的,同時(shí)在添加數(shù)據(jù)時(shí)有可能造成不必要的麻煩,今天通過本文給大家介紹下Java防止頻繁請求、重復(fù)提交的操作代碼,一起看看吧
    2022-04-04
  • IntelliJ IDEA2021.1 配置大全(超詳細(xì)教程)

    IntelliJ IDEA2021.1 配置大全(超詳細(xì)教程)

    這篇文章主要介紹了IntelliJ IDEA2021.1 配置大全(超詳細(xì)教程),需要的朋友可以參考下
    2021-04-04
  • Spring?MVC實(shí)現(xiàn)GET請求接收Date類型參數(shù)

    Spring?MVC實(shí)現(xiàn)GET請求接收Date類型參數(shù)

    這篇文章主要介紹了Spring?MVC實(shí)現(xiàn)GET請求接收Date類型參數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • JDBC建立數(shù)據(jù)庫連接的代碼

    JDBC建立數(shù)據(jù)庫連接的代碼

    這篇文章主要為大家詳細(xì)介紹了JDBC建立數(shù)據(jù)庫連接的代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • java8保姆級lambda表達(dá)式教程

    java8保姆級lambda表達(dá)式教程

    這篇文章主要介紹了Java8之后的Lambda表達(dá)式的用法,lambda表達(dá)式將大量替代匿名內(nèi)部類的使用,簡化代碼的同時(shí),更突出了原來匿名內(nèi)部類中最重要的那部分包含真正邏輯的代碼,需要的朋友可以參考下
    2023-03-03
  • Guava本地緩存的使用過程

    Guava本地緩存的使用過程

    文章介紹了使用Guava和Redis實(shí)現(xiàn)二級緩存的原因,以及如何通過Guava作為一級緩存,Redis作為二級緩存來減少數(shù)據(jù)庫壓力,提高緩存的可靠性,同時(shí),通過一個(gè)具體示例說明了如何在微服務(wù)場景中使用Guava和Redis進(jìn)行二級緩存,最后,總結(jié)了Guava的參數(shù)機(jī)制
    2025-01-01

最新評論

漯河市| 冕宁县| 三明市| 博罗县| 称多县| 本溪| 德格县| 金乡县| 万山特区| 西畴县| 福建省| 措勤县| 灵璧县| 屯昌县| 曲靖市| 金乡县| 太湖县| 鹤庆县| 聂荣县| 区。| 铜陵市| 光山县| 吐鲁番市| 庄河市| 湘潭县| 长治县| 那坡县| 福海县| 哈密市| 鄢陵县| 和静县| 贵州省| 蓬溪县| 鄂州市| 虎林市| 北宁市| 贞丰县| 旌德县| 邳州市| 来宾市| 图木舒克市|