如果您的问题是,我的代码中会收到java.lang.ArrayIndexOutOfBoundsException
,而我不明白为什么会这样。它是什么意思,我该如何避免呢?
这是关于此的最全面的Canonical信息集合
java.lang.ArrayIndexOutOfBoundsException
主题以及java.lang.IndexOutOfBoundsException
。
有很多这样的问题,所有这些问题都没有模糊的代码答案,或者大多数都是非常具体的,并且局限于手头的问题,并没有解决所有情况下完全相同的根本原因。 / p>
如果你看到属于这种一般情况的那个,而不是用更多重复的专门内容回答它,请将其标记为此副本的副本。
答案 0 :(得分:5)
JavaDoc简明扼要地陈述:
抛出表示已使用非法访问数组 指数。该指数为负数或大于或等于 数组的大小。
此异常表示您已尝试访问某个索引 数组或数组支持列表,该索引不存在。
Java使用基于
0
的索引。这意味着所有索引都以0
开头 第一个元素的索引,如果它包含任何元素。
IndexOutOfBoundsException
消息非常明确,通常采用以下形式:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
其中Index
是您请求的不存在的索引,Size
是您要编入索引的结构的长度。
正如您所看到的,Size: 1
表示唯一有效的索引是0
,而您要求的是索引1
的内容。
例如,如果您有原始
Array
个对象或基本类型 有效索引为0
到.length - 1
,在以下示例中,有效索引为0,1,2,3,
。
final String days[] { "Sunday", "Monday", "Tuesday" }
System.out.println(days.length); // 3
System.out.println(days[0]); // Sunday
System.out.println(days[1]); // Monday
System.out.println(days[2]); // Tuesday
System.out.println(days[3]); // java.lang.ArrayIndexOutOfBoundsException
这也适用于ArrayList
以及可能由Collection
支持的任何其他Array
类,并允许直接访问索引。
java.lang.ArrayIndexOutOfBoundsException
/ java.lang.IndexOutOfBoundsException
?这使用Guava将原始基元
int[]
数组转换为ImmutableList<Integer>
。然后它安全地使用Iterables
类 获取特定索引处的值并在何时提供默认值 该索引不存在。在这里,我选择-1
表示无效 指数值。
final List<Integer> toTen = ImmutableList.copyOf(Ints.asList(ints));
System.out.println(Iterables.get(toTen, 0, -1));
System.out.println(Iterables.get(toTen, 100, -1));
如果由于某种原因你无法使用Guava
,那么很容易推出自己的功能来做同样的事情。
private static <T> T get(@Nonnull final Iterable<T> iterable, final int index, @Nonnull final T missing)
{
if (index < 0) { return missing; }
if (iterable instanceof List)
{
final List<T> l = List.class.cast(iterable);
return l.size() <= index ? l.get(index) : missing;
}
else
{
final Iterator<T> iterator = iterable.iterator();
for (int i = 0; iterator.hasNext(); i++)
{
final T o = iterator.next();
if (i == index) { return o; }
}
return missing;
}
}
使用传统的for / next循环:如果需要,可以使用以下方法迭代原始
Array
知道索引和值:这容易受到一次性错误的影响,这是主要原因 一个
java.lang.ArrayIndexOutOfBoundsException
:
final int ints[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < ints.length; i++)
{
System.out.format("index %d = %d", i, ints[i]);
}
这是用原型
Array
迭代的惯用方法 如果您不需要知道实际索引,增强了for循环:
for (final int i : ints)
{
System.out.format("%d", i);
System.out.println();
}
这是使用增强功能迭代原始
Array
的安全方法 for loop 并跟踪当前索引并避免可能性 遇到java.lang.ArrayIndexOutOfBoundsException
。这使用Guava轻松将
int[]
转换为Iterable
的内容 每个项目都应包括它。
final Iterator<Integer> it = Ints.asList(ints).iterator();
for (int i = 0; it.hasNext(); i++)
{
System.out.format("index %d = %d", i, it.next());
}
如果你不能使用番石榴或你的int[]
很大,你可以自己推出ImmutableIntArrayIterator
:
public class ImmutableIntArrayIterator implements Iterator<Integer>
{
private final int[] ba;
private int currentIndex;
public ImmutableIntArrayIterator(@Nonnull final int[] ba)
{
this.ba = ba;
if (this.ba.length > 0) { this.currentIndex = 0; }
else { currentIndex = -1; }
}
@Override
public boolean hasNext() { return this.currentIndex >= 0 && this.currentIndex + 1 < this.ba.length; }
@Override
public Integer next()
{
this.currentIndex++;
return this.ba[this.currentIndex];
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
}
使用与Guava相同的代码。
如果你绝对必须拥有该项目的序数,则以下是最安全的方法。
// assume los is a list of Strings
final Iterator<String> it = los.iterator();
for (int i = 0; it.hasNext(); i++)
{
System.out.format("index %d = %s", i, it.next());
}
此技术适用于所有Iterables
,它不是index
perse,但它确实为您提供迭代中的当前位置,即使对于没有本机index
的内容也是如此。
最好的方法是始终使用来自番石榴的ImmutableLists / Set / Maps作为 好:
final List<Integer> ili = ImmutableList.copyOf(Ints.asList(ints));
final Iterator<Integer> iit = ili.iterator();
for (int i = 0; iit.hasNext(); i++)
{
System.out.format("index %d = %d", i, iit.next());
}
Array
很难处理,在大多数情况下应该避免使用。他们容易受到微妙的one off errors的影响,这些问题甚至可以追溯到BASIC
Collections
,并尽可能避免使用原始Array
结构。Immutable
类型都是首选。Guava
是现代Java开发不可或缺的工具包。答案 1 :(得分:0)
参考Java文档Class ArrayIndexOutOfBoundsException,当您尝试访问负数或大于数组大小的元素时,会抛出此异常。
考虑一下你在数组中有10个项目的情况。您可以询问系统数组中第一个到第十个项目的内容。如果您尝试询问数组中的-1项或第100项,Java将响应上述异常。现在请记住,Java中的Array是0索引的。因此,您只能传递0到9的索引值(包括0和9)。不在此范围内的任何数字都将引发上述特定错误。
为了避免这种异常,让我们回到CS101的概念,并回顾循环不变量的概念。这是确保用于存储索引的变量必须满足特定条件的条件。
以下是循环不变量的链接:wikipedia > Loop invariant