精华内容
下载资源
问答
  • 数组下标越界异常是如何产生的

    千次阅读 2020-08-04 22:24:58
    首先,ArrayList是基于数组实现的,是一个动态数组... 1、程序中报错的 at java.util.ArrayList.elementData(ArrayList.java:400) 和 at java.util.ArrayList.add(ArrayList.java:441),它们同属Add()方法。 添加...
       首先,ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。
    
       对于ArrayList而言,它实现List接口、底层使用数组保存所有元素。其操作基本上是对数组的操作。
    
       1、程序中报错的 at java.util.ArrayList.elementData(ArrayList.java:400) 和 at java.util.ArrayList.add(ArrayList.java:441),它们同属Add()方法。   
    

    添加操作,首先会调用ensureCapacityInternal(size + 1),其作用为保证数组的容量始终够用,其中size是elementData数组中元组的个数,初始为0。

    在ensureCapacityInternal()函数中,用if判断,如果数组没有元素,给数组一个默认大小,会选择实例化时的值与默认大小中较大值,然后调用ensureExplicitCapacity()。

    函数体中,modCount是数组发生size更改的次数。然后if判断,
    

    如果数组长度小于默认的容量10,则调用扩大数组大小的方法grow()。

    函数grow()解释了基于数组的ArrayList是如何扩容的。数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。
       接下来回到Add()函数,继续执行,elementData[size++] = e; 这行代码就是问题所在,当添加一个元素的时候,它可能会有两步来完成:1. 在 elementData[Size] 的位置存放此元素;2. 增大 Size 的值。
       在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
       而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。那好,我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。这就解释了为何集合中会出现null。
       但是数组下标越界还不能仅仅依靠这个来解释。我们观察发生越界时的数组下标,分别为10、15、22、33、49和73。结合前面讲的数组自动机制,数组初始长度为10,第一次扩容为15=10+10/2,第二次扩容22=15+15/2,第三次扩容33=22+22/2...以此类推,我们不难发现,越界异常都发生在数组扩容之时。
       由此给了我想法,我猜想是,由于没有该方法没有同步,导致出现这样一种现象,用第一次异常,即下标为15时的异常举例。当集合中已经添加了14个元素时,一个线程率先进入add()方法,在执行ensureCapacityInternal(size + 1)时,发现还可以添加一个元素,故数组没有扩容,但随后该线程被阻塞在此处。接着另一线程进入add()方法,执行ensureCapacityInternal(size + 1),由于前一个线程并没有添加元素,故size依然为14,依然不需要扩容,所以该线程就开始添加元素,使得size++,变为15,数组已经满了。而刚刚阻塞在elementData[size++] = e;语句之前的线程开始执行,它要在集合中添加第16个元素,而数组容量只有15个,所以就发生了数组下标越界异常!
    
    展开全文
  • 数组中常见的异常: 1.下角标越界:ArrayIndexOutOfBoundsException 原因 :因为使用的索引值没有在合理范围(0~数组的长度-1)之内 2.空指针异常:NullPointerException 原因 :只要调用属性和方法的...

    在这里插入图片描述

    /**
    	数组中常见的异常:
    	
    	1.下角标越界:ArrayIndexOutOfBoundsException
    		原因 :因为使用的索引值没有在合理范围(0~数组的长度-1)之内
    	
    	2.空指针异常:NullPointerException
    		原因 :只要调用属性和方法的那个值为null就会发生空指针异常
     */
    public class ArrayExceptionTest {
    
    	public static void main(String[] args) {
    		//1.下角标越界:ArrayIndexOutOfBoundsException
    		int[] numbers = new int[2]; //0  ~ 1是可以的
    //		System.out.println(numbers[2]); 编译错误:超出了索引值的范围
    //		System.out.println(numbers[-1]);编译错误:超出了索引值的范围
    		
    		System.out.println("----------------------------------------");
    		
    //		2.空指针异常:NullPointerException
    		String str = "aaa";
    		str = null;
    //		System.out.println(str.toUpperCase());编译错误: 因为str的内容为null
    		String[][] ps = new String[2][3];
    //		System.out.println(ps[0][0].toUpperCase());编译错误: 因为ps[0][0]的内容为null
    		String[][] ps2 = new String[2][];//二维数组的元素的默认值为null
    		System.out.println(ps2[0][0]);//编译错误:因为ps2[0]为null
    	}
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    展开全文
  • 复习内容: 数组的声明和初始化、数组的长度、数组访问、java.lang.ArrayIndexOutOfBoundsException数组下标越界异常、二维数组、java.lang.NullPointerException空指针异常 如有错误,欢迎在评论区指出,非常感谢! ...

    Java数组

    2021/4/5 周一
    复习内容: 数组的声明和初始化、数组的长度、数组访问、java.lang.ArrayIndexOutOfBoundsException数组下标越界异常、二维数组、java.lang.NullPointerException空指针异常

    如有错误,欢迎在评论区指出,非常感谢!


    数组是一种类型(与基础数据类型不一样),它能一次性定义多个同类型的变量,存放多个同类型数据。

    一、声明数组

    // 数据类型[] 数组名;
    int[] arr;
    
    // 数据类型 数组名[];
    int arr[];
    

    数据类型就是数组里存储元素的类型,[]代表数组,千万不要写漏。

    以上两种方式都可以用来声明数组,但是一般建议使用第一种。

    此时只是声明了数组,数组变量还没有被初始化。注意,在声明时不要规定数组的长度。

    二、数组初始化

    1. 动态初始化-只确定长度
    // 数据类型 []数组名 = new 数据类型[数组长度];
    int[] arr = new int[20];
    

    或者如果数组brr已经被定义了,直接将等号后面new的数组变量赋值给brr也可以

    int[] brr;
    brr = new int[20]; // 这样也可以
    

    此方式创建数组对象时,只需要指定数组的长度,数组中所有的元素的值默认为"零",具体各数据类型的"零"值为:

    数据类型“零”
    byte short int long0
    float double0.0
    booleanfalse
    char’ '(空格)
    引用数据类型null

    注意此方式创建数组对象必须使用 new 关键字,且 = 前后数据类型一致

    2. 动态初始化-确定长度和内容
    // 数据类型 []数组名 = new 数据类型[]{v1,v2,v3,v4,...};
    int[] arr = new int[]{v1,v2,v3,v4,...};
    

    此方式创建数组时,数组中的元素值也依次为{ }里所给定的元素。

    注意,[ ]内必须为空,不能在[ ]内指定数组长度,而是由{ }里元素的个数来决定数组的长度

    此方式也可以定义和赋值分开:

    int[] brr;
    brr = new int[]{v1,v2,v3,v4,...}; // 这样也是可以的
    
    2. 静态初始化
    // 数据类型 []数组名 = {v1,v2,v3...};
    int[] arr = {v1,v2,v3...};
    

    数组的静态初始化也是确定长度和内容的。

    注意,此方式不能先定义后赋值。即如果先声明数组,再用此种方式赋值是不可以的:

    int[] brr;
    brr = {v1,v2,v3...}; // 编译错误!!!
    

    三、数组的属性

    数组有一个长度属性,获得数组长度的方式为:数组名.length

    int len = arr.length; // 获得数组arr的长度
    

    在Java中允许数组的长度为0,即包含0个元素,这样的数组对象仍是一个Java对象,而且不同于null。虽然没有意义,但在语法上是合法的:

    int[] arr = new int[0];
    System.out.println(a.length);    // 输出结果为0
    

    四、访问数组元素

    访问数组元素的方式为:数组名[下标]

    arr[0]; // 访问数组a的第1个元素
    

    下标的取值范围 [0,数组长度),下标为0表示数组的第1个元素,下标的最大值为 数组长度-1

    不能超过下标范围进行元素访问,否则将引发数组中最常见的:
    java.lang.ArrayIndexOutOfBoundsException 数组下标越界异常

    比如

    int []arr ={1,2,3,4};
    

    这个数组的长度为4,如果调用arr[4],运行时就会报数组越界异常:

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    	at review.ErrorTest.main(ErrorTest.java:21)
    

    异常提示了发生错误的时候,下标的值为4

    因为下标为0表示数组的第1个元素,即这个数组的元素只有arr[0]=1, arr[1]=2, arr[2]=3, arr[3]=4,没有arr[4]

    五、二维数组

    如果数组中的元素也是数组,这样就可以组成多维数组,比如二维数组、甚至更多层次的三维数组等等(当然一般超过三维也没什么实际用处了,所以主要掌握二维数组就好了)。

    1.数组声明

    与一维数组声明类似,多一个[ ]

    // 数据类型 [][]数组名;
    int[][] arr ;
    
    2.数组初始化

    (1) 初始化一维数组(指定一维数组长度)

    数据类型 [][]数组名  = new 数据类型[二维数组长度][一维数组长度];
    int[][] arr = new int[3][4];
    

    arr这个二维数组里有3个元素,都是长度为4、数据类型为int的一维数组,此时可以取某个数组里的元素的值,不过因为没给出具体值,所以默认为0。

    可以再给一维数组里的元素赋值,如:

    arr[0][0] = 11; // 第一个数组里的第一个值
    arr[1][0] = 21; // 第二个数组里的第一个值
    arr[2][0] = 31; // 第三个数组里的第一个值
    

    另外要知道,二维数组真正存储的其实是一维数组的地址信息

    (2) 不初始化一维数组(不指定一维数组长度)

    数据类型 [][]数组名  = new 数据类型[二维数组长度][];
    int [][] arr = new int[3][];
    

    此时只说明了arr这个二维数组里有3个元素,都是数组,但这些一维数组并没有初始化过,即arr这个二维数组中的arr[0]、arr[1]、arr[2]这3个数组都是null。

    所以此时不可以取一维数组里具体元素的值,否则运行会报错
    java.lang.NullPointerException 空指针异常

    int [][] arr = new int[3][]; // 一维数组没有初始化
    System.out.println(arr[0][1]);
    
    -----------------控制台输出--------------------
    Exception in thread "main" java.lang.NullPointerException // 空指针异常
    	at review.ErrorTest.main(ErrorTest.java:21)
    

    由于一维数组arr[0]的变量没有指向任何数组对象,这个时候对该数组名进行 . 和 [ ] 的访问就会报空指针异常错误。

    需要继续将一维数组初始化后才能进行取值,而且由于一维数组分别进行初始化,所以他们的长度可以不一样

    数组名[下标] = new 数据类型[数据长度];
    arr[0] = new int[4];
    arr[1] = new int[3];
    arr[2] = new int[2];
    System.out.println(arr[0][1]);
    

    当然此时控制台还是输出0,因为数组里的元素还没有赋值,默认为0

    (3)静态初始化

    // 数据类型 [][]数组名 = new 数据类型[][]{{v1,v2,...},{v3,v4,..},{v5,...}...};
    int [][] arr = new int[][]{{v1,v2,...},{v3,v4,..},{v5,...}...};
    

    与一维数组的静态初始化类似,直接给出了二维数组中的所有一维数组的所有内容

    展开全文
  • 数组下标越界异常

    千次阅读 2017-03-31 11:27:09
    java.lang.ArrayIndexOutOfBoundsException :数组下标越界

    异常:

    03-31 11:09:24.462: E/AndroidRuntime(5743): Caused by: java.lang.ArrayIndexOutOfBoundsException: length=2; index=2


    提取信息:

    java.lang.ArrayIndexOutOfBoundsException :数组下标越界

    length=2: 长度为2

    index=2: 下标为2

    解决方法:

    android studio :

    直接点击错误,可以直接找到错误行代码。

    eclipse:

    下面一行便为异常代码 双击左键 找到错误行代码 。


    展开全文
  • 数组下标越界 :在引用数组元素时,使用的下标超过了该数组下标的应有范围。 但应注意的是: C/C++不对数组做边界检查。 可以重写数组的每一端,并写入一些其他变量的数组或者甚至是写入程序的代码。不检查下标是否...
  • 数组越界异常

    2014-07-03 11:26:31
    用try…catch…finally写一个捕捉数组越界异常例子。
  • 数组下标越界异常  查看调用的数组或者字符串的下标值是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序...
  • java关于数组下标越界

    千次阅读 2019-05-04 20:11:40
    本篇记录的就是因为数组的定长性引起的下标越界问题。 首先,我们定义一个数组。 int a =new int [5];这表示我们定义了一个Int 型,长度为5的数组。 在eclipse中,可以用数组名.length得到数组的长度。需要注意的时...
  • 数组下标越界错误

    千次阅读 2015-01-14 10:11:29
    所以这次的错误本质上是数组下标越界,是因为我没有注意下标方面的问题导致的。这个问题很好解决,我把代码稍稍进行了修改: ;font-size:14px;">for (int i = 0; i ; i++) out48[i] = in56[PC2[i]-1]; 问题解决...
  • 关于数组下标越界

    千次阅读 2018-01-21 09:54:59
    本篇记录的就是因为数组的定长性引起的下标越界问题。  首先,我们定义一个数组。 int a =new int [5];这表示我们定义了一个Int 型,长度为5的数组。 在eclipse中,可以用数组名.length得到数组的长度。需要注意...
  • 数组下标越界与内存溢出

    万次阅读 2015-12-15 14:04:02
    下标越界 在引用数组元素时,使用的下标超过了该数组下标的应有范围,但应注意的是: C/C++不对数组做边界检查。 可以重写数组的每一端,并写入一些其他变量的数组或者甚至是写入程序的代码。不检查下标是否越界...
  • Java 数组 异常处理

    千次阅读 2017-11-04 14:55:19
    如果输入数据多余5个,捕获数组越界异常,显示“请输入5个整数”。 无论是否发生异常,都输出“感谢使用本程序!” 代码: import java.util.InputMismatchException; import java.util.Scanner
  • Java运行时异常

    2021-07-26 10:16:44
    1. 数组下标越界异常 、、、java 、、、
  • 数组下标为负数出现的问题(关于数组下标越界的检查)
  • 有些语言本身就会做数组访问越界检查,比如java,访问越界时会抛出java.lang.ArrayIndexOutOfBound. C语言非常重视运行时的效率,所以没有进行数组越界检查,而C++继承了C的效率要求,也不做数组越界检查。 这样就会...
  • 异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。在Java异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类。 2、异常的分类 ...
  • 数组下标是负数

    千次阅读 2018-01-28 13:29:47
    假设整数位置的二维坐标点上都有一个温度,横坐标的范围是-3..2共6个点,纵坐标的范围是-4..3共8个点,因此,二维坐标点共48个,小宝定义了二维数组int data[6][8]; 用data[0][0]存储坐标点(-3,-4)的温度,用data[0...
  • Java数组03:三种初始化及内存分析 内存分析 Java内存分析: 堆: 存放new的对象和数组 可以被所有的线程共享,不会存放别的对象引用 栈: 存放基本变量类型(会包含这个基本类型的具体数值) 引用对象的变量...
  • 关注、星标公众号,直达精彩内容ID:技术让梦想更伟大作者:李肖遥所谓的数组越界,简单地讲就是指数组下标变量的取值超过了初始定义时的大小,导致对数组元素的访问出现在数组的范围之外,这类错误...
  • 数组访问越界

    2021-05-19 22:16:46
    由于 C 语言并不具有类似 Java 等语言中现有的静态分析工具的功能,可以对程序中数组下标取值范围进行严格检查,一旦发现数组上溢或下溢,都会因抛出异常而终止程序。也就是说,C 语言并不检验数组边界,数组的两端...
  • Java数组的练习题

    千次阅读 2020-07-02 22:30:26
    选择题 1、下列数组声明的语法格式不正确的是(C) ...3、当数组下标越界时,会发生(C) A. 系统崩溃 B. 直接跳过 C. 抛出异常 D. 中止程序 4、下面代码的运行结果为:(A) A. 55,8,5, B. 5,8,55, C. 8,5,55 D
  • 由于 C 语言并不具有类似 Java 等语言中现有的静态分析工具的功能,可以对程序中数组下标取值范围进行严格检查,一旦发现数组上溢或下溢,都会因抛出异常而终止程序。也就是说,C 语言并不检验数组边界,数组的两端...
  • 复习1:Arrays

    2019-11-20 16:39:42
    二维数组定义 二维数组的内存图 数组是什么 数组是有序数据的集合,用于存放一组数据 数组的特点 数组内元素的类型统一(与数组类型相同) 数组内元素的排序是有序的(按赋值时的顺序排列) 数组本身是不...
  •  空指针异常是运行期的异常,编译的时候是不会检查的,只有运行的时候才会抛出,一般情况下如果出现了空指针异常,事先你不知道会有这个异常,就说明你的程序有bug,当然就要找出这个bug,然后在变量调用之前先给它...
  • 数组定义 数组是相同类型数据的有序集合。 数组描述的是相同类型的若干个数据,按照一定的先后次序排序组合而成。 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。 数组声明创建 ...
  • 一、选择 下列数组声明的语法格式不正确的是(C) ...当数组下标越界时,会发生(C) A. 系统崩溃 B. 直接跳过 C. 抛出异常 D. 中止程序 下面代码的运行结果为:(A) A. 55,8,5, B. 5,8,55, C. 8,5,55
  • Java数组定义和使用

    千次阅读 多人点赞 2020-10-14 13:32:10
    目录:1.数组基本用法 :1.1什么是数组 1.2 创建数组 1.3数组的使用 2.数组作为方法的参数:2.1...数组常见操作:4.1 数组转字符串 4.2数组拷贝 4.3检查数组有序性 4.4 数组排序(冒泡) 4.5 数组数字排列 5. 二维数组
  • 数组下标为负数的问题(C语言)

    万次阅读 2018-08-20 12:25:21
    对这个数组 来说: arr[-1]是合法的,他指向a[0]的前一个元素。 但是不建议这样书写,因为a[-1]的地址是不确定的, 可能会影响到系统运行。如果同上面一题一样加上指针,可以巧妙地解决某些问题。下面贴上代码段,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,977
精华内容 9,990
关键字:

java数组下标越界异常定义

java 订阅