[英]Java: How do handle ConcurrentModificationException in this particular situation?
[英]How can it be that Java is NOT type safe in a particular situation?
今天我發現了一個非常奇怪的JVM 行為 ,一個(通常是類型安全的) List<Date>
確實在運行時持有List<MyObject>
!
我想知道怎么會發生,但在網絡上找不到任何東西。
情況就是這樣:我正在使用JRE 1.6.0_18-b07
的JBoss EAP 6.0 Server
上使用Spring Data JPA 1.2.0
。
錯誤地,在Spring Data JPA Repository
類中,在@Query
表達式中寫入了錯誤的結果類型。 應該是:
@Query("select distinct trunc(record.orderDateTime) from MyType record [...]" )
public List<Date> getOrderDates(...);
但是:
@Query("select record from MyType record [...]" )
public List<Date> getOrderDates(...);
因此,目的是加載日期列表( java.util.Date
),如果在第一個代碼片段中正確定義了查詢,則該日期工作正常。
但是編碼錯誤導致了以下結果:在運行時,實際上返回了一個List<MyType>
,即使方法的簽名定義了List<Date>
。 同樣在我的模型中, List<Date>
的屬性包含List<MyType>
。 我調試了它,無法相信我的眼睛! 我甚至可以將此列表的內容寫入JSP(我只識別這種奇怪的行為,因為嘗試從MyType
到Date
鍵入匹配時出現Spring Expression Language錯誤,因此無法再顯示JSP,其中當然不得不崩潰)。
天哪,我現在應該放棄對Java類型安全性的信任嗎?
有沒有人遇到過這樣的問題?
是否存在對此的解釋?
我可以做任何事情來解決這個問題,還是一般問題? 也許是另一個版本的JRE,JBOSS,......?
我想知道怎么會發生,但在網絡上找不到任何東西。
之所以發生這種情況,是因為泛型主要是僅編譯時功能。 元數據是根據類的類型參數,字段等來維護的......但是在執行時,類型參數(大部分)都會丟失。 例如:
Object x = new ArrayList<String>();
Object y = new ArrayList<Integer>();
System.out.println(x.getClass() == y.getClass()); // True
JVM無法區分 - 這就是為什么當您嘗試強制轉換時會收到警告的原因:
// At execution time, this cast will *really* only check for List
List<String> dodgyCast = (List<String>) y;
在大多數情況下,編譯器使用泛型保持“常規”代碼安全。 但是當你有像ORM這樣的東西通過反射或動態字節代碼提供值時,所有這些安全性就會消失。
可悲的是,由於類型擦除,可能會發生這種情況。 您在集合中設置的類型僅在編譯時檢查,而不是在運行時檢查。
問題是您的查詢未編譯,因此Java無法知道它將返回哪種對象。 為了避免這種行為,我總是創建我的查詢測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.