即使使用Optional <>仍会得到NullPointerException

时间:2019-02-08 09:33:20

标签: java java-8 optional

我正在尝试使用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;
}

欢迎任何提示或帮助:)

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

您所做的方式computer实际上并未初始化。

答案 2 :(得分:0)

假设您使用的是Java 8,这是Optional类的javadoc,它的含义是:

  

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

现在,stream()是适用于对象集合而不是单个对象的东西。 Here's stream()的文档:

  

以该集合作为源返回顺序的Stream。基本上,您需要拥有List<Computer>才能调用stream(),进行过滤并通过Optional<Computer>方法返回find

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

此外,在Java中未实例化的变量上调用任何方法总是会产生编译错误,例如:

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

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