2015-11-05 54 views
0

我想創建幾個JFormattedTextFields但總是得到ArrayIndexOutOfBoundsException,我不明白爲什麼。 變量globalZaehler2是51,然後我會得到異常。但我的循環說它必須是< field.length(這是51)。那麼globalZaehler2不能是51嗎? Eclipse中顯示我的異常,當我使用((JFormattedTextField)field[globalZaehler2]).selectAll();ArrayIndexOutOfBoundsException當使用循環創建JFormattedTextField

for (globalZaehler2 = 0; globalZaehler2 < field.length; globalZaehler2++) { 
    if (field[globalZaehler2] instanceof JFormattedTextField) { 
     ((JFormattedTextField)field[globalZaehler2]).addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
((JFormattedTextField)field[globalZaehler2]).selectAll(); 
       // do something with the text in the field 
      } 
     }); 
    } 
} 
+1

您已經提供了很多代碼,但不是一個簡短但完整的示例 - 我們甚至不知道它失敗的位置。請注意,如果您在if語句中聲明瞭局部變量,那麼您的代碼將變得更簡單:最終的JFormattedTextField formattedField =(JFormattedTextField)字段[globalZaehler2];'。然後,您可以使用對局部變量的引用來替換30次以上的演員。可讀性的好處將是*巨大*。 –

+0

現在好多了? – mavok

+1

那麼它仍然不是一個簡短但完整的程序。它看起來像'globalZaehler2'不應該在循環中達到51,如果長度是51.啊......我看到這不是一個局部變量。那就是問題所在。 –

回答

3

我們不能告訴非常容易,但名稱globalZaehler2使得它聽起來像這是一個領域,不是一個局部變量。使用字段作爲for循環中的「索引」變量幾乎是總是一個壞主意......我不記得上一次我希望在一個循環內如何改變對象的狀態。

這意味着在執行actionPerformed時,您可能已經執行了其他各種不同時間的循環,具有不同的字段長度。但是,如果您嘗試將其設置爲局部變量,您將會遇到不同的問題,因爲您在匿名內部類中引用了它 - 這意味着它需要是最終的局部變量。這就是真正的問題。

基本上,你想在actionPerformed代碼使用的globalZaehler2價值爲循環該迭代...但它循環的該迭代過程中不是執行...它執行動作監聽器時。

可以修復由環內聲明的局部變量:

for (globalZaehler2 = 0; globalZaehler2 < field.length; globalZaehler2++) { 
    // In Java 8 you wouldn't need the final part 
    final int copy = globalZaehler2; 
    // Use copy instead of globalZaehler2 within actionPerformed 
} 

然而,一個更好的解決辦法有兩個方面:

  • 當你使用for循環中的變量作爲數組的索引,並且您遍歷整個數組,使用增強for循環
  • 如果你發現自己在代碼中使用一個共同的子表達式多次,提取到一個表達

在你的情況,這將是:

// We don't know the type of field, so it's hard to guess the 
// type here. Likewise I *would* use the name field, but that's the 
// name of the array... it should probably be called fields, as it's 
// naturally plural... 
for (Object fooField : field) { 
    if (fooField instanceof JFormattedTextField) { 
     // Again, don't bother with final in Java 8 
     final JFormattedTextField textField = (JFormattedTextField) fooField; 
     textField.addActionListener(new ActionListener()) { 
      @Override public void actionPerformed(ActionEvent e) { 
       textField.selectAll(); 
       // etc 
      } 
     }); 
    } 
} 

現在你已經自然了一個新的局部變量在循環中(textField),所以可以有效地使用final,並在actionPerformed方法中使用。

+0

看起來更好,我沒有得到例外。 「字段」是一個組件數組,所以我可以用「組件」替換「對象」?謝謝你的幫助! – mavok