[英]Java wildcards and generic methods
我有一个使用Map作为字段变量的类:
private Map<String, ?> posts;
在同一个类中,我有一个通用方法:
public <T> void log(T message) {
if (isEnabled) {
Date time = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss:SS");
posts.put(sdf.format(time.getTime()), message);
}
}
但是我在posts.put语句上收到编译器错误,说:
The method put(String, capture#2-of ?) in the type Map<String,capture#2-of ?> is not
applicable for the arguments (String, T)
我对通配符和通用方法有点陌生,所以我做错了什么?
Map<String, ?>
并不意味着您可以在该映射中放入任何内容 。 这意味着值类别未知 。 但是可以是例如Foo或Bar。 而且Foo可能与任何T
类型都不兼容,因此编译器会抱怨。 请改用Map<String, Object>
或将T
参数设置为类级别,然后使用它参数化地图: Map<String, T>
当您使用不受限制的通配符类型声明Map
时:
private Map<String, ?> posts;
您将无法将除null
外的任何内容放入其中。 因为?
是任何类型的替代品。 基本上,你的Map
是所有实例的超类型Map
与String
任何类型的密钥和值。 ?
可以是Date , Number , Cat , Tiger等等。
假设您的地图是这样实例化的:
private Map<String, ?> posts = new HashMap<String, Date>();
并且方法中的type参数推断为String
,则put
方法正在执行以下操作:
posts.put(String, String);
...因此尝试在需要Date
地方添加String
类型。 当然,这将在运行时失败。 泛型通过为此发出编译器错误来避免这些问题。
您可以通过使类本身具有通用性来解决此问题,从而在方法和映射中使用相同的类型参数:
class YourClass<T> {
private Map<String, T> posts;
public void log(T message) {
if (isEnabled) {
Date time = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss:SS");
posts.put(sdf.format(time.getTime()), message);
}
}
}
另外,如注释中所述,您应该避免以time
为关键。 由于Date#getTime()
精度只有毫秒,因此,您在间隔内输入的任何内容(以毫秒为单位)都将存储为相同的键,从而覆盖该键的旧值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.