怎么说&#34;类的地图<! - ? - >列出<class =“”>&#34;在Java?

时间:2015-05-21 20:41:32

标签: java generics bounded-wildcard

说我有一个

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

2 个答案:

答案 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)

我通过使用原始ClassList(仍然无法修复这个)并使用地图包装器仅存储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);