java类型机制分为静态检查和动态检查,静态分析在编译阶段就能找出类型转换不通过的,并且在IDE中提示出来,很容易发现写法上的错误;动态检查是在运行的时候才能够确定类型是否正确。
一个动态检查的例子:
public static void main(String[] args) {
List old = new ArrayList<>();
old.add("联想");
old.add("惠普");
List<Long> newStr = old; //String类型能转换到Long型吗?
System.out.println(newStr.toString());
}
最开始的时候,认为这个程序运行会发生错误,因为 String类型不能强制转换为Long型,但是实际上程序运行正常输出,于是猜想Java的动态类型检查机制是使用的时候才会检查,在使用之前只是引用的地址到了堆上,按照猜想:List 的get方法本身不发生类型转换,那么不会出错;如果赋值给一个变量,那么会发生类型转换。
public static void main(String[] args) {
List old = new ArrayList<>();
old.add("联想");
old.add("惠普");
List<Long> newStr = old; //String类型能转换到Long型吗?
newStr.get(0);
System.out.println(newStr.toString());
}
上面代码依然没有发生错误。
public static void main(String[] args) {
List old = new ArrayList<>();
old.add("联想");
old.add("惠普");
List<Long> newStr = old; //String类型能转换到Long型吗?
Long test = newStr.get(0);
System.out.println(newStr.toString());
}
上面的代码报错了:Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
Java动态类型的机制是使用的时候进行检查,所以 "List old"使用起来是比较危险的,改为“List<String> old”后在静态检查的时候就会暴露问题.