为什么这段代码会生成ArrayIndexOutOfBoundsException?

时间:2013-03-03 08:05:58

标签: java arrays exception

我在Java(Android)中有一段代码偶尔会生成ArrayIndexOutOfBoundsException。

String characterLevel = mCharacterModel.CharacterLevel() >= 
        MessageModel.CharacterLevels.length ? "Hyperion Overlord" : 
        MessageModel.CharacterLevels[mCharacterModel.CharacterLevel()];

方法mCharacterModel.CharacterLevel()始终为1或更多。

MessageModel.CharacterLevels数组定义如下,包含大约50个元素。

public static final String[] CharacterLevels = { "Title", "Title" };

问题的实质是如果超出了数组的大小,则优雅地默认为另一个数据源。

我一定错过了什么。这是将字符串设置为默认为字符串的错误方法吗?

我到处都找到了我能想到的解决方案,我担心的是我刚刚错过了上述逻辑中的一些基本缺陷。

任何帮助或建议表示赞赏。

3 个答案:

答案 0 :(得分:1)

您的代码在逻辑上看起来等同于以下内容:

int level = mCharacterModel.CharacterLevel();
String[] arr = MessageModel.CharacterLevels;
String characterLevel = level < arr.length ? 
        arr[level] : 
        "Hyperion Overlord";

如果它在边界内,它显然只会索引到数组中。我不同意关于数组索引的-1修饰符的其他答案,因为您的逻辑检查应该防止该级别对于数组来说太大。

我可以在原始代码(或我看不到的东西)中看到的唯一可能导致问题的区别是(按可能性顺序):

  1. 您不止一次致电mCharacterModel.CharacterLevel() - 如果随后调用而改变,则可能是错误来源。也许第一次通话时为1,第二次通话为3?
  2. mCharacterModel.CharacterLevel()可能会返回一个负数 - 我会在索引到数组之前添加一个检查以确保它也是>= 0
  3. MessageModel.CharacterLevels可能是在多个线程上被访问的东西,它在长度检查和访问之间被修改,导致问题。

答案 1 :(得分:0)

String characterLevel = mCharacterModel.CharacterLevel() >= MessageModel.CharacterLevels.length-1 ? "Hyperion Overlord" : MessageModel.CharacterLevels[mCharacterModel.CharacterLevel()];

这应该有用,长度不是0,所以你应该去&#39; -1&#39;当根据长度计算时。

答案 2 :(得分:0)

数组索引从0开始,因此您可能希望使用:

int index = mCharacterModel.CharacterLevel() - 1;
String characterLevel = index >= MessageModel.CharacterLevels.length ? "Hyperion Overlord" : MessageModel.CharacterLevels[index];

如果值始终为1或更大,则需要从0开始。 另一个问题 - 你最好不要两次调用函数CharacterLevel()并使用结果。最好将值存储在局部变量中,并在两个地方使用它。