1

我有一个从哈希图中获取某些东西的方法,一个简化的例子(这没有多大意义,但现在已经足够好了)是:

private Map<String,String> map = new HashMap<String,String>();

public String get(String key) {
    return map.get(key);
}

当给定键明显不存在条目时,此方法可以返回 null。问题是,我想用@NonNull(因为它在无数地方使用,我不喜欢 Intellij 向我发送关于生成 NPE 的检查警告的垃圾邮件,我不想关闭该检查,我也不想在我调用这个方法的任何地方检查返回的值是否不同于 null。这是因为我总是使用这个方法和一堆总是在地图中的键。所以由于程序逻辑,这个方法是必然会返回一个@NonNull值。

我很想用 注释它@NonNull,但谁知道有人可能会用某个地方定义的键以外的东西来调用它,实际上会导致 NullPointerException。你会怎么办?一个断言对我来说听起来很诱人。或者你会改变方法来抛出一个 RuntimException 吗?还是一个断言错误?

谢谢。

编辑:

这是实际的实现:

/**
 * Typesafe heterogeneous container pattern - implementation
 */
public class HandlersMap {

    private final Map<Class<? extends TableHandler>, TableHandler> handlers;

    public HandlersMap() {
        handlers = new HashMap<Class<? extends TableHandler>, TableHandler>();
        putHandler(RolesTableHandler.class, new RolesTableHandler());
        putHandler(UsersTableHandler.class, new UsersTableHandler());
        putHandler(DevicesTableHandler.class, new DevicesTableHandler());
    }

    private <T extends TableHandler> void putHandler(@NonNull final Class<T> type, @NonNull final T instance) {
        handlers.put(type, type.cast(instance));
    }

    @NonNull
    public <T extends TableHandler> T getHandler(@NonNull final Class<T> type) {
        assert handlers.get(type) != null;
        return type.cast(handlers.get(type));
    }

    public Collection<TableHandler> values() {
        return handlers.values();
    }

    public int size() {
        return handlers.size();
    }

    public Map<Class<? extends TableHandler>, TableHandler> getMap() {
        return this.handlers;
    }

}
4

1 回答 1

6

在不验证给定密钥是否存在的情况下进行注释@Nonnull绝对是错误的做法。

由于您似乎表明给定的键应该存在,这意味着缺少的键是无效的参数,因此检查这种情况并 IllegalArgumentException为缺少的元素抛出一个将是正确的做法。

或者,根据您的地图的初始化方式,您可能需要考虑为您的键值创建一个枚举,使用 anEnumMap而不是 a HashMap,并让您的get()方法采用这个 enum 而不是自由格式String。这样,您将进行一些编译时检查以确保也使用正确的值。

即使在这种情况下,您仍然需要检查是否存在,以防请求的枚举值尚未添加到地图中。

于 2014-06-05T16:54:56.963 回答