【问题标题】:The functionality of the || operator|| 的功能操作员
【发布时间】:2014-07-07 16:33:14
【问题描述】:

我创建了一个 equals 方法。我相信我可以通过两种方式做到这一点,但 java 似乎并不同意。这是我知道的第一个有效的示例。

    public class HelloWorld {

     public boolean equals(Object rhs){
        if(this==rhs){
            return true;
        }else if( rhs==null || this.getClass() != rhs.getClass()){
            return false;
        }else{

            HelloWorld tmp =(HelloWorld)rhs;
            return true;
        }
     }

     public static void main(String[] args){
        HelloWorld c = new HelloWorld();
        System.out.println(c.equals(null));

     }  
}

这是第二个不起作用的例子。而不是返回 false 我得到一个空指针异常。

    public class HelloWorld {

     public boolean equals(Object rhs){
        if(this==rhs){
            return true;
        }else if(this.getClass() != rhs.getClass() || rhs==null){
            return false;
        }else{

            HelloWorld tmp =(HelloWorld)rhs;
            return true;
        }
     }

     public static void main(String[] args){
        HelloWorld c = new HelloWorld();
        System.out.println(c.equals(null));

     }  
}

那么我的问题......这两段代码之间的唯一区别是我写的第一段代码

    rhs ==null ||...

在第二部分中,它位于 OR 运算符的另一边

    ...|| rhs==null

为什么第一种情况不会给我一个 Nullpointer 而第二种情况呢?为什么我在 OR 运算符的哪一边写布尔语句很重要?

【问题讨论】:

    标签: java operators logic


    【解决方案1】:

    这很重要,因为|| 作为条件“OR”运算符,如果左表达式为true,则不会计算右表达式,因为结果已经可以确定。这被称为“短路”行为。

    Section 15.24 of the JLS 涵盖此内容:

    条件或运算符 ||运算符就像 | (§15.22.2),但仅当其左侧操作数的值为 false 时才评估其右侧操作数。

    不计算右手表达式,因此避免使用NullPointerException

    && 条件“AND”运算符,也是“短路”,仅当左侧为 true 时才计算右侧。)

    【讨论】:

      【解决方案2】:

      如果|| 运算符的左侧计算结果为true,则不会执行|| 的右侧,根据JLS section 15.24

      条件或运算符|| 运算符类似于|(第15.22.2 节),但仅当其左侧操作数的值为false 时才计算其右侧操作数。

      所以在您的第一种情况下,rhs == null 的计算结果为 true,因此不会执行 rhs.getClass() - 否则它 抛出 NullPointerException

      在第二种情况下,您正在无条件执行 rhs.getClass(),因此出现异常。

      如果您使用| 而不是||,则在这两种情况下都会出现异常。

      【讨论】:

        【解决方案3】:

        我建议您按照 Joshua Bloch 的“Effective Java”第 3 章中的方法正确实现 equals 方法。

        如果你实现了equals,你也应该实现hashCode。

        【讨论】:

          【解决方案4】:

          当你使用'||'这是具有短路行为的条件或,如果第一个条件为真,则不评估第二个条件。

          例如,如果您使用 (A||B) --- 如果 A 为真,则不会评估 B。

          这就是为什么在 rhs 为空的情况下会出现空指针异常的原因。

          第一组代码实际上是正确的,因为您在那里正确处理了 Null 情况,而第二组的情况则不然。

          如果您希望同时评估这两个条件并且不希望出现短路行为,您可以使用“|”运算符而不是 '||'。

          所以在 (A|B) 的情况下——即使 A 为真,B 也会被评估。

          【讨论】:

            猜你喜欢
            • 2020-11-16
            • 1970-01-01
            • 2017-11-26
            • 2017-02-09
            • 2017-03-19
            • 1970-01-01
            • 1970-01-01
            • 2021-11-13
            • 2015-12-11
            相关资源
            最近更新 更多