Java中@Nonnull注解用于返回null的方法

3

我有一个从哈希表中获取某些内容的方法,以下是一个简化的例子(虽然没有太多意义但已足够):

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个回答

7
使用@Nonnull进行注释而不验证给定的键是否存在肯定是错误的做法。
由于您似乎表明预期存在给定的键,因此缺少键是无效参数,因此检查此情况并针对缺少元素抛出IllegalArgumentException将是正确的做法。
或者,根据映射初始化的方式,您可能需要考虑为键值创建一个枚举,使用EnumMap而不是HashMap,并让您的get()方法采用此枚举而不是自由格式的String。这样,您将具有一些编译时检查以确保使用正确的值。
即使在那种情况下,您仍然需要检查是否存在,以防请求的枚举值尚未添加到映射中。

1
喜欢enumMap的想法 - 我甚至不知道这样的东西存在。Map本身是一个类,所有的键都在构造函数中添加。这是Joschua Bloch提出的类型安全异构映射容器模式的一种变体。我会试验一下看看能否根据你的建议做出一些东西,谢谢:) - sakis kaliakoudas
1
我最终还是选择了hashMap,但为了以防万一,我添加了一个断言。问题是,我的键只能是特定类的子类,而且所有这些子类已经在map中了。所以这个情况不太可能失败。然而,如果有什么可以失败的,迟早会失败!:) EnumMap对于我的情况来说实现起来相当困难,所以我暂时放弃了它。如果你感兴趣,我可以给你看一下我实际实现的代码!:D - sakis kaliakoudas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接