2013-03-03 193 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

相關問題