繁体   English   中英

Java通配符和通用方法

[英]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是所有实例的超类型MapString任何类型的密钥和值。 ? 可以是DateNumberCatTiger等等。

假设您的地图是这样实例化的:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM