Java中的可选条件运算符导致NullPointerException

Java中的可选条件运算符导致NullPointerException,java,java-8,nullpointerexception,optional,conditional-operator,Java,Java 8,Nullpointerexception,Optional,Conditional Operator,我有一个Dto列表,其中包含两个参数:类型和值。现在,我想在列表中找到一个类型为“C”的元素,并读取值 执行以下java代码时,我得到一个我不理解的NullPointerException: class TestDto { private String type; private Double value; TestDto(final String type, final Double value) { this.type = type;

我有一个Dto列表,其中包含两个参数:类型和值。现在,我想在列表中找到一个类型为“C”的元素,并读取值

执行以下java代码时,我得到一个我不理解的NullPointerException:

class TestDto
{
    private String type;
    private Double value;

    TestDto(final String type, final Double value)
    {
        this.type = type;
        this.value = value;
    }

    public String getType() { return type; }
    public Double getValue() { return value; }
}

类型为“C”的list元素的值为null,因此我希望Double值变为null——这是可以的。这在if语句内部工作,它按预期打印“if output=null”

我希望if语句与条件运算符相同。你知道我为什么会得到NullPointerException吗

一些评论:

  • 我已把问题降到最低限度。我知道有更简单的方法来获取Dto的值。我只是想理解为什么上面显示的代码不起作用

  • 如果搜索类型“A”或“B”,则不会出现错误,并且该值会打印两次

  • 替换值“0”应改为“0d”,但它用“0”编译。但是,将代码更改为:


在我将替换值更改为“0d”之前,它不会编译。也许这有助于解决问题。

这是一个有点滑稽的问题。您的三元运算符在此:

optional.isPresent() ? ((TestDto) optional.get()).getValue() : 0;
正在使用基元零。Java决定首先将null
Double
取消装箱到一个基本的Double,这样两个结果的类型相同,并且会导致
NullPointerException

如果将
0
替换为
Double.valueOf(0)
,则三元值的两个结果均为
Double
类型,因此无需进行拆箱

optional.isPresent() ? ((TestDto) optional.get()) : Double.valueOf(0);

另一方面,所有使代码在某些地方看起来如此丑陋的可怕的转换都是由于您没有使用
Optional
的通用版本。如果使用通用版本,代码可能如下所示:

Optional<TestDto> optional = testList.stream().filter(typePredicate).findFirst();
       // ^ Generics!

if(optional.isPresent()){
    System.out.println("if-output = " + optional.get().getValue());
}

Double value = optional.isPresent() ? optional.get().getValue() : Double.valueOf(0);

System.out.println(value);
Optional=testList.stream().filter(typePredicate.findFirst();
//^仿制药!
if(可选的.isPresent()){
System.out.println(“if output=“+optional.get().getValue());
}
Double value=可选。isPresent()?可选.get().getValue():Double.valueOf(0);
系统输出打印项次(值);

尽量不要使用原始类型。它应该是
可选的
您确定您有
私有双精度值
在您的
TestDto
中,而不是
私有双精度值?否则,为
final Double value
传递
null
将导致构造函数()内部崩溃。我在
testList.add上得到一个NullPointerException(newtestdto(“C”,null))@markbernard我的错。我为自己编写了类DTO,以将其转换为可运行的。修复了它。我没有发布TestDto代码,但我会在上面的文本中将其更改为Double,否则你是对的,它会在构造函数中崩溃。哇,我甚至没有想到这一点。很好的答案。顺便说一句,为了让它更漂亮,我们还可以这样做:
Double value=optional.map(TestDto::getValue).orElseGet(0D)@davida。仔细的这不是一个确切的替代品。如果
getValue
返回null,那么当您确实需要null时,您将得到0。感谢您提示使用泛型可选值@mgerbracht在IDE中启用所有Java编译器警告。然后它会告诉你一些错误,比如原始类型。
optional.isPresent() ? ((TestDto) optional.get()).getValue() : 0;
optional.isPresent() ? ((TestDto) optional.get()) : Double.valueOf(0);
Optional<TestDto> optional = testList.stream().filter(typePredicate).findFirst();
       // ^ Generics!

if(optional.isPresent()){
    System.out.println("if-output = " + optional.get().getValue());
}

Double value = optional.isPresent() ? optional.get().getValue() : Double.valueOf(0);

System.out.println(value);