hibernate返回的数据类型是List<Object>的,所以我不小心把其转换为List<Long>,结果并没有报错,但当我调用 List<Long>的get方法获取数据时报错:类型转换错误,下面来复现这个问题。
oracle中的类型是Number,在hibernate中对应的其实是BigDecimal,
hibernate对BigDecimal做了类型擦除,所以Java代码获取到的是List<Object>的结果。
运行以下代码模拟 hibernate返回数值类型,并进行类型转换
import java.util.ArrayList;
import java.util.List;
import java.math.BigDecimal;
class Untitled {
public static void main(String[] args) {
System.out.println("A");
List<BigDecimal> decimals = new ArrayList<>();
decimals.add(new BigDecimal(100));
decimals.add(new BigDecimal(101));
List objs = decimals;
List<Long> lll = (List<Long> )objs;
System.out.println("B");
Long aaa = (Long)lll.get(0);
System.out.println("C");
}
}
以下为上述代码执行结果:
A
B
Note: /usercode/file.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Exception in thread "main" java.lang.ClassCastException: class java.math.BigDecimal cannot be cast to class java.lang.Long (java.math.BigDecimal and java.lang.Long are in module java.base of loader 'bootstrap')
at file.main(file.java:14)
好了,问题来了,为什么在执行 List<Long> lll = (List<Long> )objs;时,代码没报类型转换错误,反而在后面使用时Long aaa = (Long)lll.get(0);才报错呢?
结论:
因为类型擦除,所以 :
List<Long> lll = (List<Long> )objs;等价于 List lll = (List)objs;
因此这里看似用了类型转换,实际上什么都没有做。
而在执行 Long aaa = (Long)lll.get(0);时,lll.get(0)返回的Object类型对象实则是BigDecimal类型的实例,此时发现BigDecimal不能转换成Long,所以报错