Java可选&t;T&>问题,我这样做正确吗?

2022-05-06 00:00:00 java-8 java optional

我有一个"坏习惯",当某些东西不存在时,我会把null抛到其他地方,比如枚举数。

示例:

private enum Foo {
    NULL(1, null, 2),
    NOT_NULL(3, new Bar(), 4);

    private int a, c;
    private Bar b;

    Foo(int a, Bar b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
}

所以现在我尝试将我的代码转换为使用Optional<T>,就像每个人建议的那样,但我不确定我这样做是否正确。

以下是我的代码(修剪后的枚举):

public static enum Difficulty { 
    EASY, MEDIUM, HARD
}

public static enum SlayerTasks {
    NONE(0, Optional.empty(), Optional.empty(), Optional.empty()),
    NPC(1, Optional.of(Difficulty.EASY), Optional.of("That one place."), Optional.of(1));

    private int taskId;
    private Optional<Difficulty> difficulty;
    private Optional<String> location;
    private Optional<Integer> npcId;

    SlayerTasks(int taskId, Optional<Difficulty> difficulty, Optional<String> location, Optional<Integer> npcId) {
        this.taskId = taskId;
        this.difficulty = difficulty;
        this.location = location;
        this.npcId = npcId;
    }

    public int getTaskId() {
        return taskId;
    }

    public Difficulty getDifficulty() {
        return difficulty.get();
    }

    public String getLocation() {
        return location.get();
    }

    public int getNpcId() {
        return npcId.get();
    }
}

让我感到困扰的是参考#get()Foundhere的文档,其中显示:

如果此可选参数中存在值,则返回该值,否则引发NoSuchElementException异常。

因此,我认为为了防止出现这种情况,我应该将getter包装在#isPresent()中,但是我不知道如何返回空。

这是正确的做事方式吗,还是我错过了什么?我不是在寻找"解决办法",我是在寻找有关效率和适当实践的信息。


解决方案

您需要问问自己,如果没有任何可返回的内容,您希望Getter做什么。

实际上只有四个选项:

  1. 返回空值(但随后返回到您试图避免的位置);
  2. 让您的getter返回Optional<T>而不是T
  3. 如果未设置,则返回默认值;
  4. 引发异常。

我会选择2,除非对于缺省值应该是什么有一个非常明确的正确答案。只有当客户端代码应该总是知道是否有什么东西存在并且只有在有的时候才请求它时,4才是合适的(这将是不寻常的,但不是不可能的)。

相关文章