||的功能操作者

时间:2014-07-07 16:33:14

标签: java operators logic

我创建了一个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));

     }  
}

这是第二个不起作用的例子。

是一个nullpointerexception而不是返回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运算符的哪一边写入布尔语句是否重要?

4 个答案:

答案 0 :(得分:6)

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

Section 15.24 of the JLS涵盖了这一点:

  

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

未评估右手表达式,因此避免使用NullPointerException

&&条件“AND”运算符,也是“短路”,如果左侧为true,则仅评估右侧。)

答案 1 :(得分:2)

如果左侧按JLS section 15.24评估为||,则true运算符的右侧不会执行:

  

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

因此,在第一种情况下,false的计算结果为true,因此rhs == null未执行 - 否则抛出rhs.getClass()

在第二种情况下,您无条件地执行NullPointerException,因此例外。

如果您使用rhs.getClass()代替|,则会在两种情况下都获得例外。

答案 2 :(得分:1)

我建议您遵循Joshua Bloch的方法,从他的" Effective Java"中正确实施equals方法。第3章。

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

答案 3 :(得分:0)

正在使用' ||'这是条件OR与短路行为,如果第一个条件成立,则第二个条件未被评估。

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

这就是为什么在rhs为空的情况下你得到空指针异常的原因。

第一组代码实际上是正确的,因为你正确处理那里的空案例,这与第二集的情况不同。

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

因此,在(A | B)的情况下---即使A为真,也会评估B.