JAVA泛型容器的类型检查
来源:互联网 发布:淘宝怎么免费装修店铺 编辑:程序博客网 时间:2024/05/29 13:04
泛型容器是通过指定容器包含对象的类型,由编译器保证对象类型的正确性,在编译阶段就能检查出类型错误。如下列将List<Long>对象longList赋予一个List<GenericTest>对象gtList,会报编译错误。
public class GenericTest
{
public static List<Long> longList = Arrays.asList (1L ,2L);
public static void main(String args[]){
//下面这条语句编译会报错
List<GenericTest> gtList=longList ;
}
}
如果这只是在编译检查,那么我们是否可以绕过编译检查呢?我们先将List<Long>对象longList赋予一个raw List变量rawList,然后再将这个rawList强制类型转换成List<GenericTest>类型。结果编译通过了,并且运行时也没有报错。我们成功地骗过了编译器。
public class GenericTest
{
public static List<Long> longList = Arrays.asList (1L ,2L);
public static void main(String args[]){
List rawList= longList;
//这个是可以编译通过,成功的骗过了编译器
List<GenericTest> gtList= rawList;
}
}
接着,如果我们使用List<GenericTest>类型的变量gtList,那会发生什么事。注意gtList引用的容器里面放的实际上是Long类型对象。这会发生什么事,会引用一段错误的内存吗?结果我们发现String result = gtList.get(0).stringValue;语句正确地在运行时抛出 java.lang.ClassCastException异常。分析 main函数的字节码可知, 在该语句之前插入了类型转换检查字节码,导致了这个异常的抛出。看来Java设计者已经考虑到这一点,在泛型容器对象使用前加上了类型检查,防止这样的情况。
public class GenericTest
{
public static List<Long> longList = Arrays.asList (1L ,2L);
public StringstringValue ="ss";
public static void main(String args[]){
List rawList= longList;
//这个是可以编译通过,成功的骗过了编译器
List<GenericTest> gtList= rawList;
//会在运行时抛出 java.lang.ClassCastException
String result =gtList.get (0).stringValue;
}
}
字节码分析如下:
0 getstatic #28<variable/GenericTest.longList> //获得类变量longList, 并放入栈顶
3 astore_1 //将栈顶引用放入第一个本地变量 rawList
4 aload_1 //将第一个本地变量rawList,放入栈顶
5 astore_2 //将栈顶引用放入第二个本地变量tgList,这里我们可以看到将rawList赋值给tgList,没有任何类型检测,所以运行通过
6 aload_2
7 iconst_0
8 invokeinterface #43<java/util/List.get> count 2
13 checkcast #1 <variable/GenericTest> // 检测类型转换,当我们使用容器中对象时,会有类型检测,导致抛出java.lang.ClassCastException
16 getfield #37<variable/GenericTest.stringValue> // 获得实例属性,并放入栈顶
19 astore_3 //将栈顶引用放入第三个本地变量 result
20 return
- JAVA泛型容器的类型检查
- 【java】泛型和类型安全的容器ArrayList
- JAVA 泛型的 raw 类型带来的其 【编译时类型检查功能丧失】
- [疯狂Java]泛型:泛型的底层原理(类型擦除、原生类型、编译前检查)
- Java 容器类型的打印
- Java类型检查
- 存放混合类型对象的JAVA容器
- java容器之间的类型转换
- Java 类型安全的异构容器
- JAVA中泛型和类型安全的容器
- Java容器类浅析一-----容器类的类型
- 严格的类型检查
- js的类型检查
- 检查变量的类型
- 利用java反射机制绕过编译时的类型检查
- 基本类型的容器
- 从头认识java-13.11 对比数组与泛型容器,观察类型擦除给泛型容器带来什么问题?
- javascript变量的类型检查
- Jquery $.trim(str)去除字符串空格
- 人类语言的力量和无力
- Girl_iOS100天学iOS的第十六天(锻炼身体)
- sgu113
- int* 转double* 时的内存越界访问
- JAVA泛型容器的类型检查
- 如何使用android独立工具链快速移植开源项目
- 深入理解Java Proxy机制
- PlayerPrefsX的用法
- GDB
- 上机作业5
- RDD:基于内存的集群计算容错抽象
- 【Monogdb】MongoDB之十大应用设计技巧
- SDUT2128排序二叉树的中序遍历