1. 程式人生 > >【Java原始碼】ArrayList原始碼(上)關於get方法的遺留問題

【Java原始碼】ArrayList原始碼(上)關於get方法的遺留問題

 問題重現

  在ArrayList原始碼的get方法中,傳參為負的異常是如何產生的?   原始碼只判斷了index > size

    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }

  為了弄清楚這個問題,我發了個帖子,好在得到了完美的回答

   在此鳴謝   使用者   Surrin1999

為了方便,現在將他的解釋拿過來看

授人以魚不如授人以漁  為了把這個問題講好 我們復現一次這個問題 測試程式碼

1

2

3

4

5

6

7

8

9

10

11

12

13

import java.util.ArrayList;

public class TestList {

public static void main(String[] args) {

ArrayList<Integer> list = new ArrayList<>();

list.add(1);

list.add(2);

list.add(3);

list.add(4);

System.out.println(list.get(-1));

}

}

在第11行打一個斷點 然後進入debug(除錯)模式  然後點選單步跳入(注意不是單步跳過  不知道的話後面的圖會有提到) 顯然 你也知道rangeCheck只是檢測了index > size  那麼問題自然出在return這裡 繼續單步跳入

你會發現 此時忽然進入了一個異常類裡面 再結合我的紅色箭頭 想必你已經猜到一點了 繼續單步跳入 很明顯了    return時丟擲的異常不是ArrayList裡呼叫的 是jvm檢測到陣列越界而自動丟擲的通過跳入到這裡我們可以知道 上面那個異常類是繼承自RuntimeException  而只有繼承自Exception的異常才需要在原始碼中顯式定義    這一張圖裡的紅色箭頭指向就是單步跳入 它右邊的就是單步跳過 總結 :遇到一些匪夷所思的問題 很多時候我們只要拆分為一小塊慢慢剖析,如打斷點除錯,就能縮小問題的範圍,最終找出答案所在 希望能對你有幫助

這個問題的產生也在於自己忽視了JVM本身的一些東西,只在意了程式碼方面的實現,忽視底層原理,要想把一個東西學好,其底層是沒辦法忽略的,受益匪淺,謝過大佬!