说我有一个
HashMap<?, List<?>> map = new HashMap<>();
map.put(String.class, new ArrayList<Long>());
以下代码将编译。
但是,我想编译失败,因为ArrayList不适用于String类型。
另外,我的通配符仅限于某些特定的接口(例如Exception),因此我想我应该将<? extends Exception>
放在某处。
我如何实现上述目标?
示例测试:
map.put(String.class, new ArrayList<String>()); //Fail because String is not an Exception
map.put(IOException.class, new ArrayList<FileNotFoundException>()); // Fail because FileNotFoundException is not an IOException even though it is a subclass of it
map.put(FileNotFoundException.class, new ArrayList<IOException>()); // I suppose I'm fine with this.
map.put(IllegalArgumentException.class, new ArrayList<IllegalArgumentException>()); // Succeed
map.put(NumberFormatException.class, new ArrayList<ServerException>()); // Fail again because the two classes don't match
map.put(ClientDecodingException.class, new ArrayList<ClientDecodingException.class>); // Succeed again since the map takes in a wildcard Exception
答案 0 :(得分:1)
我相信你无法在地图的关键字和声明价值之间表达这种通用约束。您可以将地图声明为
Map<Class<Exception>, List<Exception>>
然后编译器不知道列表中的例外必须扩展键的类。
我没有看到很多方法可以确保检查此约束,除非使用诸如
之类的方法 <T extends Exception> void addToMap(Class<? extends T> aClass, List<T> aList) {
map.put(aClass, aList);
}
希望这有帮助。
答案 1 :(得分:1)
我通过使用原始Class
和List
(仍然无法修复这个)并使用地图包装器仅存储Exception
来完成此操作:
public class ExceptionMapWrapper {
private Map<Class, List> myMap;
public ExceptionMapWrapper() {
myMap = new HashMap<>();
}
//relevant methods for the test: put and get
public <T extends Exception> void put(Class<T> clazz, List<T> list) {
myMap.put(clazz, list);
}
public <T extends Exception> List<T> get(Class<T> key) {
return myMap.get(key);
}
}
这是一个简单的测试:
ExceptionMapWrapper exceptionMapWrapper = new ExceptionMapWrapper();
Class<IOException> clazz = IOException.class;
List<IOException> list = new ArrayList<>();
exceptionMapWrapper.put(clazz, list);
//compiler errors, uncomment to see them
//exceptionMapWrapper.put(String.class, new ArrayList<String>());
//exceptionMapWrapper.put(IOException.class, new ArrayList<ClassCastException>());
//exceptionMapWrapper.put(IOException.class, new ArrayList<SQLException>());
List<IOException> ioExList = exceptionMapWrapper.get(clazz);
//compiler error, uncomment to see
//List<SQLException> sqlExList = exceptionMapWrapper.get(clazz);