![](/img/trans.png)
[英]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.