繁体   English   中英

为什么在这种情况下为原始工作返回 null?

[英]Why does returning null for a primitive work in this case?

这段丑陋的代码确实可以编译,但如果s == null则抛出 NPE

public static boolean isNullOrEmpty(String s)
{
    return s != null ? s.isEmpty() : null;
}

虽然这不是(如预期的那样):

public static boolean isNullOrEmpty(String s)
{
    if(s != null)
        return s.isEmpty();
    else
        return null;
}

我知道他们两个都是错误的,但当我在我们的源代码中找到第一段代码时,我很惊讶它确实编译了。

编辑:这是来自 Java 7 的 JLS 的相关部分。我猜第一个语句适用,但粗体语句适用。

15.25 条件运算符? :

[...]

条件表达式的类型确定如下:

[...]

  • 如果第二个和第三个操作数之一是基本类型 T,而另一个的类型是对 T 应用装箱转换(§5.1.7)的结果,则条件表达式的类型是 T。

[...]

  • 否则,第二个和第三个操作数的类型分别为 S1 和 S2。 令 T1 为对 S1 应用装箱转换产生的类型,令 T2 为对 S2 应用装箱转换产生的类型。 条件表达式的类型是将捕获转换 (§5.1.10) 应用于 lub(T1, T2) (§15.12.2.7) 的结果。

第一个有一个三元运算符,其结果类型为Boolean NPE 正在将null转换为boolean

它实际上是这样的:

Boolean temp = s != null ? s.isEmpty() : null; //no problems here
return temp; //crash when temp==null

第二个是试图返回错误的类型(对象而不是原始类型)——因此无法编译。

类似于JAVA 中的 Tricky 三元运算符

三元运算符使用 JLS 中引用的规则进行自动装箱:

拳击转换

这条规则是必要的,因为条件运算符 (§15.25) 将装箱转换应用于其操作数的类型,并将结果用于进一步的计算。

问题在于 Java 中的自动装箱。 问题是由于第二个操作数不是第三个。

public static boolean isNullOrEmpty(String s)
    {
        return s != null ? null : null;
    }

这段代码不会编译

条件运算符的 JLS

三元运算符需要为两个操作数找出最合适的返回类型。

因此,它允许对返回类型进行一些“修饰”。

如您的第一个代码片段所示:

public static boolean isNullOrEmpty(String s)
{
    return s != null ? s.isEmpty() : null;
}

s.empty()返回原始boolean ,而第三个操作数返回null 所以最具体的常见返回类型是Boolean 编译器的工作就像将行替换为:

return s != null ? s.isEmpty() : (Boolean)null; 

返回类型方法需要一个boolean原语,所以编译器说:“酷,我只需要拆箱我的结果。”不幸的是, null不是拆箱的,会导致难看的 NPE。

用你的第二个片段:

public static boolean isNullOrEmpty(String s)
{
    if(s != null)
        return s.isEmpty();
    else
        return null;
}

没有对预返回类型进行额外的“润色”,因为编译器没有链接这段代码中的两个返回语句 => 对它来说可能是一项太难的工作。

因此,在这种情况下,代码甚至无法编译是合乎逻辑的,因为nullBoolean没有关联,所以。 不会发生任何演员表。

要编译它,它应该写成:

public static boolean isNullOrEmpty(String s)
    {
        if(s != null)
            return s.isEmpty();
        else
            return (Boolean)null;
    }

但在尝试拆箱时并不能阻止著名的 NPE 发生;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM