如何避免java.lang.ArrayIndexOutOfBoundsException? [英] How to avoid java.lang.ArrayIndexOutOfBoundsException?

查看:1094
本文介绍了如何避免java.lang.ArrayIndexOutOfBoundsException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你的问题是的我在我的code得到一个 java.lang.ArrayIndexOutOfBoundsException ,我不明白为什么它正在发生。这是什么意思,我怎样能避免呢?


  

这意味着是最COM prehensive 规范的信息,此集合
   java.lang.ArrayIndexOutOfBoundsException 的话题。


  
  

有这样和所有的人或任渺无多的问题
  code答案,或者大部分他们都非常具体,
  定位于眼下的问题,不解决根本问题
  导致这实际上是在所有情况下是相同的。




  

如果你看到一个根据本一般的情况下下跌,而不是回答更多的重复专门的内容,将其标记为这一个的副本。



解决方案

什么是java.lang.ArrayIndexOutOfBoundsException?

借助的JavaDoc 简略地指出:


  

抛出,表明阵列已与非法访问
  指数。该指数是负或大于或等于所述
  阵列的大小


是什么原因导致这样的情况发生?


  

这异常意味着你已经尝试在访问索引
  数组或数组支持列表和指标不存在。


  
  

Java使用 0 基于索引。这意味着所有的指标入手 0 作为
  如果它包含的任何元素的第一个元素的索引。


  
  

例如,如果你有一个原始的 Array对象或原始类型
  有效的索引 0 。长度 - 1 ,在下面的例子中,有效的指标将是 0,1,2,3,


 最后弦乐天[] {星期日,星期一,星期二}
的System.out.println(days.length); // 3
的System.out.println(天[0]); //星期天
的System.out.println(天[1]); //星期一
的System.out.println(天[2]); //周二
的System.out.println(天[3]); // java.lang.ArrayIndexOutOfBoundsException

这也适用于的ArrayList ,以及可通过<$ C备份任何其他收藏班$ C>阵列,并允许对指数的直接访问。

如何避免 java.lang.ArrayIndexOutOfBoundsException

当指数直接访问:


  

此使用番石榴以原始原始<$ C $转换C> INT [] 阵列的
  <一href=\"http://docs.guava-libraries.google$c$c.com/git-history/release/javadoc/com/google/common/collect/ImmutableList.html\"相对=nofollow> ImmutableList&LT;整数GT; 。然后,它使用了 Iterables 类安全
  在一个特定的指数获得的价​​值,并提供一个默认值时,
  该指数不存在。在这里,我选择了 1 来表示一个无效的
  指数值。


 最终名单,LT;整数GT; TOTEN = ImmutableList.copyOf(Ints.asList(整型));
的System.out.println(Iterables.get(TOTEN 1,0,-1));
的System.out.println(Iterables.get(滔天,100,-1));

如果您不能使用番石榴由于某种原因,很容易推出自己的功能做这同样的事情。

 私有静态&LT; T&GT;吨得到(@Nonnull最终可迭代&LT; T&GT;迭代,最终诠释指数,@Nonnull最终t丢失)
{
    如果(指数℃下){返回丢失; }
    如果(迭代器的instanceof名单)
    {
        最终名单&LT; T&GT; L = List.class.cast(迭代器);
        返回l.size()&LT; =指数? l.get(指数):丢失;
    }
    其他
    {
        最后的迭代器&LT; T&GT;迭代= iterable.iterator();
        的for(int i = 0; iterator.hasNext();我++)
        {
            最终t O = iterator.next();
            如果(我==指数){返回O; }
        }
        回到缺少的;
    }
}

当迭代:


  

下面是惯用的方式来遍历一个原始的阵列如果你需要
  要知道的索引和值:


  
  

这是容易的一次性误差的哪些是主要原因
  的 java.lang.ArrayIndexOutOfBoundsException


使用传统的/下一个循环:

 最终诠释整数[] = {1,2,3,4,5,6,7,8,9,10};
的for(int i = 0; I&LT; ints.length;我++)
{
    System.out.format(索引%=%d个,我,整数[I]);
}

使用增强的for / each循环:


  

下面是遍历原始阵列的惯用方式
  增强的for循环的 的,如果你不需要知道实际的指标:


 的(最终诠释我:整数)
{
    System.out.format(%D,我);
    的System.out.println();
}

使用类型安全的迭代器:


  

下面是遍历安全的方式原始阵列增强
  循环
的并跟踪当前索引,并避免的可能性
  遇到一个 java.lang.ArrayIndexOutOfBoundsException


  
  

此使用番石榴可以轻松地转换成 INT [] 的东西可迭代
  每个项目应该包括它。


 最后的Iterator&LT;整数GT;它= Ints.asList(整型).iterator();
的for(int i = 0; it.hasNext();我++)
{
    System.out.format(索引%=%d个,我,it.next());
}

如果您不能使用番石榴或 INT [] 是巨大的,你可以滚你自己的 ImmutableIntArrayIterator 这样

 公共类ImmutableIntArrayIterator实现迭代器&LT;整数GT;
{
    私人最终诠释[] BA;
    私人诠释CURRENTINDEX;    公共ImmutableIntArrayIterator(@Nonnull最终诠释[] BA)
    {
        this.ba = BA;
        如果(this.ba.length大于0){this.currentIndex = 0; }
        其他{CURRENTINDEX = -1; }
    }    @覆盖
    公共布尔规则hasNext(){返回this.currentIndex&GT; = 0&放大器;&安培; this.currentIndex±1℃; this.ba.length; }    @覆盖
    下一个公开整数()
    {
        this.currentIndex ++;
        返回this.ba [this.currentIndex]
    }    @覆盖
    公共无效删除(){抛出新UnsupportedOperationException异常(); }
}

和使用相同的code,你会与番石榴。

如果你绝对的必须具有序的项目下面是做到这一点的最安全的方式。

  //假设洛杉矶是一个字符串列表
最后的迭代器&LT;串GT;它= los.iterator();
的for(int i = 0; it.hasNext();我++)
{
    System.out.format(索引%=%s的,我,it.next());
}

该技术适用于所有 Iterables ,它不是一个首页深灰色,但它确实给你的当前位置在迭代即使事情没有原生首页

最安全的方式:


  

最好的办法是始终使用<一个href=\"http://docs.guava-libraries.google$c$c.com/git-history/release/javadoc/com/google/common/collect/ImmutableList.html\"相对=nofollow> ImmutableLists / <一个href=\"http://docs.guava-libraries.google$c$c.com/git-history/release/javadoc/com/google/common/collect/ImmutableSet.html\"相对=nofollow>设置 / <一个href=\"http://docs.guava-libraries.google$c$c.com/git-history/release/javadoc/com/google/common/collect/ImmutableMap.html\"相对=nofollow>地图番石榴为的
  好:


 最终名单,LT;整数GT;伊犁= ImmutableList.copyOf(Ints.asList(整型));
最后的迭代器&LT;整数GT;个人所得税= ili.iterator();
的for(int i = 0; iit.hasNext();我++)
{
    System.out.format(索引%=%d个,我,iit.next());
}

摘要:


  1. 使用原始阵列都难以处理,并应在大多数情况下是可以避免的。他们很容易受到有时微妙一次性误差这已经困扰着新来的程序员甚至回基本的日子

  2. 现代的Java成语使用正确的类型安全的收藏,并避免如果在所有可能使用原始的阵列结构。

  3. 永恒类型现在几乎所有情况下pferred在$ P $。

  4. 番石榴是现代Java开发中不可缺少的工具。

If your question is I am getting a java.lang.ArrayIndexOutOfBoundsException in my code and I do not understand why it is happening. What does it mean and how can I avoid it?

This is meant to be the most comprehensive Canonical collection of information on this java.lang.ArrayIndexOutOfBoundsException topic.

There are many questions like this and all of them or either vague no code answers, or mostly they are extremely specific and localized to the question at hand and do not address the root cause which is actually the same in all cases.


If you see one that falls under this general case, rather than answer it with more duplicate specialized content, mark it as a duplicate of this one.

解决方案

What is java.lang.ArrayIndexOutOfBoundsException?

The JavaDoc curtly states:

Thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.

What causes it to happen?

This exception means that you have tried to access an index in an array or array backed list and that index does not exist.

Java uses 0 based indexes. That means all indexes start with 0 as the index of the first element if it contains any elements.

For example if you have an raw Array of objects or primitive types the valid indexes are 0 to .length - 1, in the following example the valid indexes would be 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

This also applies to ArrayList as well as any other Collection classes that may be backed by an Array and allow direct access to the the index.

How to avoid the java.lang.ArrayIndexOutOfBoundsException?

When accessing directly by index:

This uses Guava to convert the raw primitive int[] array to an ImmutableList<Integer>. Then it uses the Iterables class to safely get the value at a particular index and provides a default value when that index does not exist. Here I chose -1 to indicate an invalid index value.

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

If you can't use Guava for some reason it is easy to roll your own function to do this same thing.

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

When iterating:

Here is the idiomatic ways to iterate over a raw Array if you need to know the index and the value:

This is susceptible to one off errors which are the primary causes of an java.lang.ArrayIndexOutOfBoundsException:

Using a traditional for/next loop:

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

Using an enhanced for/each loop:

Here is the idiomatic way to iterate over a raw Array with the enhanced for loop if you do not need to know the actual index:

for (final int i : ints)
{
    System.out.format("%d", i);
    System.out.println();
}

Using a type safe Iterator:

Here is the safe way to iterate over a raw Array with the enhanced for loop and track the current index and avoids the possibility of encountering an java.lang.ArrayIndexOutOfBoundsException.

This uses Guava to easily convert the int[] to something Iterable every project should include it.

final Iterator<Integer> it = Ints.asList(ints).iterator();
for (int i = 0; it.hasNext(); i++)
{
    System.out.format("index %d = %d", i, it.next());
}

If you can not use Guava or your int[] is huge you can roll your own ImmutableIntArrayIterator as such:

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

And use the same code as you would with Guava.

If you absolutely must have the ordinal of the item the following is the safest way to do it.

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

This technique works for all Iterables, it is not an index perse but it does give you the current position in the iteration even for things that do not have a native index.

The safest way:

The best way is to always use ImmutableLists/Set/Maps from Guava as well:

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

Summary:

  1. Using raw Array are difficult to work with and should be avoided in most cases. They are susceptible to sometimes subtle one off errors which have plague new programmers even back to the days of BASIC
  2. Modern Java idioms use proper type safe Collections and avoid using raw Array structures if at all possible.
  3. Immutable types are preferred in almost all cases now.
  4. Guava is an indispensable toolkit for modern Java development.

这篇关于如何避免java.lang.ArrayIndexOutOfBoundsException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆