This question already has answers here: Generics and inheritance: need a complex Map instance                                                                    (2个答案)                                                                                        5年前关闭。                                Formatter<T>知道如何将T格式化为字符串:public interface Formatter<T> { String format(final T t);}我想要一个Map格式化程序,一个用于Integer,一个用于Date等:Map<Class, Formatter> formatters;预期用途为:formatters.put(Integer.class, new Formatter<Integer>() { public String format(Integer i) { return i.toString; }});有什么方法可以强制键值在Class类型上达成一致?如果我说put(Integer.class, new Formatter<Integer>(){...})可以,但是put(Integer.class, new Formatter<Date>(){...})不能?我现在正在尝试使用的是什么?作为类型:Map<Class<?>, Formatter<?>> formatters;但是,然后我不能在此地图内使用格式化程序:Object obj = Integer.valueOf(15);formatters.get(obj.getClass()).format(obj);Error: The method format(capture#3-of ?) in the type Formatter<capture#3-of ?> is not applicable for the arguments (Object)任何澄清都将受到欢迎。 最佳答案 不幸的是,如果没有一些较早声明的<T>泛型类型,就无法在键和值之间创建这种关系。同样,此类也不应该在类中固定,因此它应该能够在每次put调用中进行更改。如果这是一个选择,请考虑使用具有通用类型的方法,例如@SuppressWarnings("unchecked")public static <T> void putSafe(Class<T> key, Formatter<T> value) { formatters.put(key, (Formatter<Object>) value);}这会将一些值放入地图,例如可能是您课程中的私有字段private static Map<Class<?>, Formatter<Object>> formatters = new HashMap<Class<?>, Formatter<Object>>();同样,您不能使用format参考中的Formatter<?>方法。这种引用可以指向Formatter<Integer>或Formatter<Date>或任何其他类型的Formatter,并且编译器将无法确定您使用的是哪种格式,因此存在对Formatter<Date>对象使用Integer的风险(为何Java不允许您在add引用中使用List<?>方法是一个相同的问题-因为我们不知道哪种列表引用可以保存,如果实际上在苹果列表中列出)要解决此问题,您可以明确地说映射将存储add(new Banana),并且由于List<Apple>只要扩展对象,它就能接受任何类型的数据。这种方法的唯一问题是Formatter<Object>不能引用format [1],因此您必须将传递的格式化程序显式转换为Formatter<Object>,这通常可能是不安全的[2],并且编译器会警告您有关以下内容的信息:它,但是在这种情况下,您应该没问题,所以您可以取消此警告。[1]像Formatter<Integer>一样不能引用Formatter<Object>,因为通过水果列表,您可以将List<Fruit>添加到List<Apple>列表中[2]将Banana强制转换为Apples通常不是最好的主意,编译器会警告我们这种方法
10-05 17:56