如何在Java中运用短路运算符与逻辑运算符

  介绍

本篇文章给大家分享的是有关如何在Java中运用短路运算符与逻辑运算符,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

1,逻辑运算符(部分)

符号名称,和短路与运算符| |短路或运算符,与运算符|或运算符

对于理工科学习者来说,逻辑运算是较为基础的概念,通常会在大一的离散数学课程中有所了解。在Java以及更多c语言中,,和|会分别表示逻辑运算中的与,或,他们的运算结果与我们在数学书中所学的逻辑运算规则并无差异。但是,在实际编程的过程中,我们反而会更多使用,,和| |,甚至不少同学都不了解,,|两个运算符,那么,这究竟是为什么呢?

2,短路运算符

让我们来回到最初学习逻辑运算时解决问题的真值表,以”或运算”为例:

ab结果truetruetruetruefalsetruefalsetruetruefalsefalsefalse

a和b中,<强>只要至少有一个为真强,最终输出的结果则为真。那么,从算法优化的角度来思考问题的话,我们为了经过最少步骤还能输出可靠的结果,我们便可以把”或运算“定义为,有一个事实,就输出真实的。

由此,”或运算”可以被优化为:从左向右,遇到有一个布尔表达式为真,则返回真,不进行之后的运算。

与之相似的,“与运算”可以被优化为:从左向右,遇到有一个布尔表达式为假,则返回假,不进行之后的运算。

故此,短路运算符被设计了出来。但为了兼顾“执行命令并返回”,“纯粹的数学计算”等多种应用场景,传统的非短路逻辑运算符也没有被短路逻辑运算符而取代。

此外,对于连写的短路运算符,如func1 () | | func2 () | | func3 () | | func4(),编译器也会为此优化,我们不妨来阅读这一部分的字节码来验证这个结论:

public  static  void  main (String [], args), {   boolean 才能;b1 =, func1 (), | |, func2 (), | |, func3 (), | |, func4 ();   System.out.println才能(“- - - - - - - - - - - - - - - - - -“);   boolean 才能;b2 =, func1 (), |, func2 (), |, func3 (), |, func4 ();   }//,func1(),安康;func4(),这里

短路”或“的字节码如下:

0:, invokestatic  # 7,,,,,//, Method  func1: Z ()   3:ifne ,, 24   6:,invokestatic  # 13,,,,,//, Method  func2: Z ()   9:,ifne , 24   12:,invokestatic  # 16,,,,,//, Method  func3: Z ()   15:ifne ,, 24   18:,invokestatic  # 19,,,,,//, Method  func4: Z ()   21:ifeq , 28   24:iconst_1   25:goto , 29岁   28:iconst_0   29:istore_1

3行,9行,15行的ifne是将栈顶元素与0(假)相比,如果不为假则跳转到24行将常量1(真正的)入栈,完成赋值,会跳过其余的执行。直到最后21行,才将最后方法结果的值再与0相比,如果还是0,则将常量0入栈,完成赋值。

普通“或”等字节码如下:

38:, invokestatic  # 7,,,,,//, Method  func1: Z ()   41:invokestatic  # 13,,,,,//, Method  func2: Z ()   44:ior   45:invokestatic  # 16,,,,,//, Method  func3: Z ()   48:ior   49:invokestatic  # 19,,,,,//, Method  func4: Z ()   52:ior   53:istore_2

则是普通的或运算,无跳转,顺序执行最后赋值。

3,应用与陷阱

在最起初,笔者重新认识短路运算符是在这样一段代码中:

public  LoginCheckDTO  XxxLoginCheck (String 密码),{//some 代码   if  (==,, password  null  | |, password.length (),==, 0,), {   return  LoginCheckDTO.EMPTY_PASSWORD;   }//some 代码   }

当时笔者认为,如果密码为空,在尝试调用password.length()时,会抛出空指针异常,故此写法不好。但在后来进行测试的时候,发现这样写并没有问题,查阅相关资料便了解了短路运算符的概念。

在这个例子中,当执行密码==null返回真正的时候,随后的表达式将不会被执行,就不存在抛出异常的情况了。这便是短路运算符较为常用的一个应用场景。

除此之外,我们还要警惕短路运算符导致的指令执行不完整。

譬如如下应用场景,我们希望利用条件语句来判断所有灯在上一状态是否都开着,并且无论如何我们希望最后打开所有的灯。但是我们错误使用了短路运算符:

public  boolean  checkAndTurnOnAll (), {   return  checkAndTurnOn1 (),,,, checkAndTurnOn2 ();   }      private  boolean  checkAndTurnOn1 (), {   boolean  check =, check1 ();   turnOn1 ();   return 检查;   }      private  boolean  checkAndTurnOn2 (), {   boolean  check =, check2 ();   turnOn2 ();   return 检查;   }

如何在Java中运用短路运算符与逻辑运算符