【问题标题】:Still getting NullPointerException even if using Optional<>即使使用 Optional<> 仍然会出现 NullPointerException
【发布时间】:2019-02-08 09:33:20
【问题描述】:

我正在尝试使用 Optional 来检查 nullpointexception 并以防它发生然后打印一些其他内容。 (https://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html)

我将声卡设置为 null,但我仍然收到 nullpointerexception,但我想通过可选来避免它。

主类(计算机)

import java.util.Optional;

public class Computer {
    public Optional<SoundCard> getSoundcard() {
        return soundcard;
    }

    public void setSoundcard(Optional<SoundCard> soundcard) {
        this.soundcard = soundcard;
    }

    private Optional<SoundCard> soundcard = null ;


    public static void  main(String[] args)
    {
         Optional<Computer> computer = Optional.of(new Computer());;


        String verion = computer.flatMap(Computer::getSoundcard)
            .flatMap(SoundCard::getUsb)
            .map(USB::getVersion)
            .orElse("Unknown");
        System.out.println(verion);
    }
}

另一类声卡

import java.util.Optional;

public class SoundCard {

    public Optional<USB> getUsb() {
        return usb;
    }

    public void setUsb(Optional<USB> usb) {
        this.usb = usb;
    }

    private Optional<USB> usb = null;
}

另一个类 (USB)

public class USB {

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    private String version;
}

欢迎任何提示或帮助:)

【问题讨论】:

  • 只需初始化变量Optional&lt;Computer&gt; computer ;
  • 那是因为它没有被初始化。 => 可选 计算机;计算机computer1 =新计算机(); String verion = computer.Stream().flatMap(Computer::getSoundcard) 另外,它是stream(),不是Stream()
  • 变量计算机未初始化。这意味着您必须创建计算机选项或创建空选项。例如 Optional computer = Optional.of(new Computer()) 或 Optional computer = Optional.empty()。我不确定Optionals是否有方法stream(),但如果是真的,它必须以小写开头。

标签: java java-8 optional


【解决方案1】:
// computer initialization
Optional<Computer> computer = Optional.of(new Computer());

// Applying operations to Optional<Computer>: stream() is for Collections, not for Optionals
String version = computer.flatMap(Computer::getSoundcard)
            .flatMap(SoundCard::getUsb)
            .map(USB::getVersion)
            .orElse("Unknown");

更新

此外,像Computer.soundcard(类型为Optional)这样的字段不应使用null值初始化,而是使用Optional.empty(),以避免NullPointerException或类似错误...

所以完整的代码是

public class Computer {
    public Optional<SoundCard> getSoundcard() {
        return soundcard;
    }

    public void setSoundcard(Optional<SoundCard> soundcard) {
        this.soundcard = soundcard;
    }

    private Optional<SoundCard> soundcard = Optional.empty() ;


    public static void  main(String[] args)
    {
        Optional<Computer> computer = Optional.of(new Computer());

        String version = computer
                .flatMap(Computer::getSoundcard)
                .flatMap(SoundCard::getUsb)
                .map(USB::getVersion)
                .orElse("Unknown");
        System.out.println(version);
    }
}

class SoundCard {

    public Optional<USB> getUsb() {
        return usb;
    }

    public void setUsb(Optional<USB> usb) {
        this.usb = usb;
    }

    private Optional<USB> usb = Optional.empty();
}

class USB {

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    private String version;
}

【讨论】:

  • 其实我会删除我的支持这个。
  • 但是当我将声卡设置为 null 时,它会抛出 nullpointerexception ,但我使用 optional to 看不到空指针异常,请帮忙。
  • @Raam 从不将Optional 设置为null。使用Optional.empty()
  • 我认为问题出在ComputerSoundCard 类中:其中字段(如Computer.soundcard` 是可选的,不应将其设为null,而应设为@ 987654336@。我更新了我的回复,包括所有课程...
  • @Raam 好吧,Optional 只是一个和其他任何类一样的类,所以当然你可以将null 分配给它,它会编译。但是Optional 类背后的想法是避免必须分配null,这首先是导致NullPointerExceptions 的原因。因此,它提供了自己的 empty() 方法,您应该在需要表示缺失值时使用该方法。
【解决方案2】:

你应该初始化计算机变量:

Optional<Computer> computer = Optional.of(new Computer());

你这样做的方式,computer 真的没有初始化。

【讨论】:

    【解决方案3】:

    假设您使用的是 Java 8,这里是 Optional 类的 javadoc,它是这么写的:

    一个容器对象,它可能包含也可能不包含非空值。如果一个 值存在,isPresent() 将返回 true,get() 将返回 价值。

    现在,stream() 是对一组对象而不是单个对象起作用的东西。 Here'sstream() 的文档:

    返回一个以此集合为源的顺序流。基本上,您需要有一个List&lt;Computer&gt; 才能调用stream(),进行过滤并通过find 方法返回Optional&lt;Computer&gt;

    当您尝试在单个对象而不是集合上调用 stream() 时,它会显示错误。

    另外,在java中对非实例化变量调用任何方法总是会产生编译错误,例如:

    Optional<Computer> computer ;
    computer.stream(); // compilation error
    

    因此,我们需要先对其进行初始化,并确保我们根据引用类型调用了正确的方法。

    【讨论】:

    • 实际上,他在一个未实例化的变量上调用 Stream(),这是(第一个和第二个)问题
    • 请注意,Optional 因为 Java-9 也有 stream()
    • @Stultuske nullpointer 感谢您的输入,我已经更新了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2016-08-13
    相关资源
    最近更新 更多