Java泛型动态类型安全问题( Collections.checkedInterface )
2013-04-04 20:48
441 查看
因为可以向Java SE5之前的代码传递泛型容器,所以旧式代码仍旧有可能会破坏您的容器,Java SE5的java.util.Collections中有一组便利工具,可以解决在这种强况下的类型检查问题,它们是:静态方法checkedCollection()、checkedList()、checkedMap()、checkedSet()、checkedSortedMap()和checkedSortedSet()。这些方法每一个都会将您希望动态检查的容器当作第一个参数接受,并将您希望强制要求的类型作为第二个参数接受。
受检查的容器在您试图插入类型不正确的对象时抛出ClassCastException,这与泛型之前的(原生)容器形成了对比,对于后者来说,当您将对象从容器中取出时,才会通知您出现了问题。
在后一种情况中,您知道存在问题,但是不知道罪魁祸首在哪里,如果使用受检查的容器,就可以发现谁在试图插入不良对象。
让我们用受检查的容器来看看“将猫插入到狗列表中”这个问题。这里,oldStyleMethod()表示遗留代码,因为它接受的是原生的List,而@SuppressWarnings("unchecked")注解对于压制所产生的警告是必需的:
//: generics/CheckedList.java
// Using Collection.checkedList().
import typeinfo.pets.*;
import java.util.*;
public class CheckedList {
@SuppressWarnings("unchecked")
static void oldStyleMethod(List probablyDogs) {
probablyDogs.add(new Cat());
}
public static void main(String[] args) {
List<Dog> dogs1 = new ArrayList<Dog>();
oldStyleMethod(dogs1); // Quietly accepts a Cat
List<Dog> dogs2 = Collections.checkedList(
new ArrayList<Dog>(), Dog.class);
try {
oldStyleMethod(dogs2); // Throws an exception
} catch(Exception e) {
System.out.println(e);
}
// Derived types work fine:
List<Pet> pets = Collections.checkedList(
new ArrayList<Pet>(), Pet.class);
pets.add(new Dog());
pets.add(new Cat());
}
}
结果输出:java.lang.ClassCastException: Attempt to insert class typeinfo.pets.Cat element into collection with element type class typeinfo.pets.Dog
运行这个程序时,您会发现插入一个Cat对于dogs1来说没有任何问题,而dogs2立即会在这个错误类型的插入操作上抛出一个异常。还可以看到,将导出类型的对象放置到将要检查基类型的受检查容器中是没有问题的。
受检查的容器在您试图插入类型不正确的对象时抛出ClassCastException,这与泛型之前的(原生)容器形成了对比,对于后者来说,当您将对象从容器中取出时,才会通知您出现了问题。
在后一种情况中,您知道存在问题,但是不知道罪魁祸首在哪里,如果使用受检查的容器,就可以发现谁在试图插入不良对象。
让我们用受检查的容器来看看“将猫插入到狗列表中”这个问题。这里,oldStyleMethod()表示遗留代码,因为它接受的是原生的List,而@SuppressWarnings("unchecked")注解对于压制所产生的警告是必需的:
//: generics/CheckedList.java
// Using Collection.checkedList().
import typeinfo.pets.*;
import java.util.*;
public class CheckedList {
@SuppressWarnings("unchecked")
static void oldStyleMethod(List probablyDogs) {
probablyDogs.add(new Cat());
}
public static void main(String[] args) {
List<Dog> dogs1 = new ArrayList<Dog>();
oldStyleMethod(dogs1); // Quietly accepts a Cat
List<Dog> dogs2 = Collections.checkedList(
new ArrayList<Dog>(), Dog.class);
try {
oldStyleMethod(dogs2); // Throws an exception
} catch(Exception e) {
System.out.println(e);
}
// Derived types work fine:
List<Pet> pets = Collections.checkedList(
new ArrayList<Pet>(), Pet.class);
pets.add(new Dog());
pets.add(new Cat());
}
}
结果输出:java.lang.ClassCastException: Attempt to insert class typeinfo.pets.Cat element into collection with element type class typeinfo.pets.Dog
运行这个程序时,您会发现插入一个Cat对于dogs1来说没有任何问题,而dogs2立即会在这个错误类型的插入操作上抛出一个异常。还可以看到,将导出类型的对象放置到将要检查基类型的受检查容器中是没有问题的。
相关文章推荐
- PHP弱类型安全问题总结
- java泛型的内部原理:类型擦除以及类型擦除带来的问题
- PHP弱类型的安全问题详细总结
- 解决android4.2以下addJavaScriptInterface不安全问题
- php弱类型安全问题
- 解决spring使用动态代理类型转换失败的问题--java.lang.ClassCastException: com.sun.proxy.$Proxy$ cannot be cast to ...今天
- java中的类型安全问题-Type safety: Unchecked cast from Object to ...
- java泛型中类型擦除以及类型擦除带来的问题
- java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题
- PHP代码审计笔记--弱类型存在的安全问题
- java泛型实现及类型擦除相关问题
- 解决spring使用动态代理类型转换失败的问题--java.lang.ClassCastException: com.sun.proxy.$Proxy$ cannot be cast to ...
- JPA criteria 动态查询:类型安全与面向对象
- java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题
- extjs4.1 动态加载 checkboxgroup 后checked 为true老是失效的问题+combobo自动选择特定记录
- Oracle数据库中字段定义为Char类型,Hibernate用该字段进行动态绑定参数查询,获取不到结果的问题
- Java泛型函数的运行时类型检查的问题
- 遇到动态调用Parameters .AddWithValue()参数类型问题的解决方法
- java泛型的内部原理、类型擦除以及类型擦除带来的问题