2010-09-25 46 views
0

我想適應春季JDBC,但是什麼錯誤我使用這些匿名類,我們不能通過任何局部變量,除非他們是最後的,可能很容易安排,但如果我需要循環數組或集合呢? 我不能聲明「FedModel fm」是最終的,因爲它在循環中被重新初始化,但我需要調用execute方法100次。這是我遇到問題的具體場景,因爲我不知道如何將BLOB插入到數據庫中。辛苦與春天匿名/回調類的數據持久

for (int i = 0; i < fedModels.size(); i++) { 
     FedModel fm = fedModels.get(i); 

     jdbcTemplate.execute("INSERT INTO items (name, video_blob) VALUES (?, ?)", 
        new AbstractLobCreatingPreparedStatementCallback(lobHandler) { 
        protected void setValues(PreparedStatement ps, LobCreator lobCreator) 
         throws SQLException { 
          ps.setString(1, fm.getName()); 
          ps.setString(2, fm.getDifficultyLevel()); 
          ps.setString(3, fm.getEquipment()); 
          lobCreator.setBlobAsBinaryStream(ps, paramIndex, contentStream, contentLength);              
          } 
       }); 

} 

我能想到的唯一的事情,是創建一個擴展AbstractLobCreatingPreparedStatementCallback並添加構造函數fedModels這樣我就可以做內環路的靜態嵌套類。但僅使用JDBC會更容易。

回答

1

...但我的錯誤是使用這些匿名類,在這裏我們可以不通過任何局部變量,除非他們是最後...

這不是春天的錯。它是Java編程語言的屬性。

基本上,Java語言(至少Java 6和更早版本)不支持關閉,這將允許匿名類實例訪問和更新實例的封閉範圍中的局部變量。作爲一種解決方法,該語言允許您訪問包含final的局部變量。這是通過將相應變量的值複製到匿名類實例中並將它們存儲在隱藏變量中實現的(不使用閉包)。

在您的具體情況下,簡單的解決方案是將fm聲明爲final。如果您需要訪問匿名類中的循環變量,則可以聲明最終副本;例如

for (int i = 0; i < 10; i++) { 
    final int ii = i; 
    new Thread(new Runnable(){ 
     public void run() { 
      System.err.println(ii); 
     } 
    }).start(); 
} 
+0

如果一個最終變量被分配了一個對象的引用,它將始終引用同一個對象。如果它被分配了一個原始值,它可能只做一次,並且該值不能被改變。你如何認爲我可以宣佈「FedModel fm」變量和「我」變量final,如果他們都分配了100次? – lisak 2010-09-25 10:13:41

+0

對不起,我認爲在for循環中聲明的變量會被重新分配100次,但我只是試過了,因爲它在for循環的1個循環中被初始化了一次,但在第二個循環中被重新創建,對吧? – lisak 2010-09-25 10:40:42

+0

@lisak - 這是正確的。 – 2010-09-25 12:26:42