java @Nonnull注释在返回null的方法中

时间:2014-06-05 16:17:26

标签: java annotations notnull

我有一个从hashmap中获取内容的方法,一个简单的例子(它没有多大意义,但现在已经足够了)是:

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?或AssertionError?

感谢。

编辑:

这是实际的实施:

/**
 * 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;
    }

}

1 个答案:

答案 0 :(得分:4)

使用@Nonnull进行批注而不验证给定密钥是否存在绝对是错误的做法。

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

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

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