2013-03-03 107 views
2

我有一段Java(Android)中的代码偶尔会产生ArrayIndexOutOfBoundsException。为什么此代码会生成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" };

问题的本质是大约正常默认为数据的另一来源,如果数组的大小已经被超过。

我必须缺少一些东西。这是不正确的方式来设置字符串默认为字符串?

我在寻找解决方案,我可以想到的所有地方,我担心我只是错过了上述逻辑中的一些基本缺陷。

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

+0

所以我很好奇 - 假设你解决了它,结果是什么问题? – Krease 2013-03-03 21:21:40

+0

崩溃来自Google Play开发者控制台上的Star Traders RPG,所以我只是猜测我修复了它。我从来没有能够自己复制崩溃。我按照建议进行了修改 - 现在我只调用mCharacterModel。CharacterLevel()一次,以防其他线程更新角色的统计信息。我还添加了一个检查来确保级别不是负面的。 CharacterLevels []永远不会被修改,所以我跳过了。我还重构了与您在下面提出的建议类似的代码。现在我注意'错误报告',并保持我的手指交叉。再次感谢! – 2013-03-04 07:12:40

回答

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可能是在多个线程上访问的东西,它在长度检查和访问之间被修改,导致问题。
0
String characterLevel = mCharacterModel.CharacterLevel() >= MessageModel.CharacterLevels.length-1 ? "Hyperion Overlord" : MessageModel.CharacterLevels[mCharacterModel.CharacterLevel()]; 

这应该工作,当基于长度计算长度不为0基础的,所以你应该去“-1”。

+0

''='不会覆盖那个吗?如果长度为50,则只有当'CharacterLevel()'为49或更小时才会索引到数组中,这应该是有效的...... – Krease 2013-03-03 08:10:13

0

数组索引从0开始的,所以你可能要使用:

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

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

+0

对-1修饰符不同意。逻辑对于确保级别不超过数组长度是正确的(假设函数始终返回相同的值)。请参阅下面的[我的答案](http://stackoverflow.com/a/15183844/836214),稍微改写后的版本,使其更加明显。 – Krease 2013-03-03 08:30:07

+0

-1将帮助他得到0值,因为它说的值总是1以上。正如我的回答所述,需要合并CharacterLevel的调用。 – BobTheBuilder 2013-03-03 08:37:40

+0

但是,如果CharacterLevel的值总是严格小于数组长度 - 即不是> = - 那么超出数组边界(-1会很有用)不是问题。 – Krease 2013-03-03 16:20:05

相关问题