前面提到逻辑运算只能操作布尔变量,这其实是不严谨的,因为经过Java编程实现,会发现“&”、“|”、“^”这几个逻辑符号竟然可以对数字进行运算。譬如下面的代码就直接对数字分别开展了“与”、“或”、“异或”运算:

		// 3的二进制为00000011,7的二进制为00000111
int andNumber = 3&7; // 对两个数字进行“按位与”运算
System.out.println("andNumber="+andNumber);
int orNumber = 3|7; // 对两个数字进行“按位或”运算
System.out.println("orNumber="+orNumber);
int xorNumber = 3^7; // 对两个数字进行“按位异或”运算
System.out.println("xorNumber="+xorNumber);

上述代码也能成功编译运行,运行结果如下所示:

andNumber=3
orNumber=7
xorNumber=4

究其原因,这三个逻辑符号原是按位逻辑运算。所谓按位逻辑,指的是先将操作数转成二进制,再对二进制的操作数逐位进行逻辑运算,最后把每位的逻辑结果重新拼成一个二进制的运算值。例如数字3的二进制表达为00000011,数字7的二进制表达为00000111,那么对这两个二进制数进行“按位与”运算,得到的二进制结果为00000011即数字3;同样对这两个二进制数进行“按位或”运算,得到的二进制结果为00000111即数字7;继续对这两个二进制数进行“按位异或”运算,得到的二进制结果为00000100即数字4。
以上的实验结果,说明了逻辑与、或、异或符号实质是按位逻辑运算,之前的布尔变量只是按位逻辑的一种运算类型。既然按位逻辑比较的是左右两边的各个二进制位,就意味着必须先确定左右两边的操作数值,然后才能对两个操作数进行按位运算。这么看来,按位逻辑并非真正意义上的逻辑操作,正常情况的逻辑运算应当具备下列特征:
1、只判断真和假,不判断0和1,更不是什么逐位判断;
2、对于“与”运算,一旦左边的操作数为假,则不管右边为何,运算结果一定为假;
3、对于“或”运算,一旦左边的操作数为真,则不管右边为何,运算结果一定为真;
对比发现,按位逻辑不但不符合上述的第一点特征,也不符合第二点和第三点特征,因为按位逻辑需要左右两边都确定之后,才能墨守成规进行逻辑运算。显然这样做并不经济,倘若左边操作数就能确定运算结果,那又何苦画蛇添足进行右边的冗余计算?为解决按位逻辑存在的问题,Java引入了新的短路符号来帮忙,包括短路与符号“&&”和短路或符号“||”,短路的意思是:如果左边已经接通,那就不绕道右边了。
话虽如此,但又如何证明短路逻辑是否真的高效呢?下面通过一个例子来分辨按位逻辑和短路逻辑之间的区别,关键在于逻辑符号的右边需要修改变量值,为此引入了自增符号“++”。具体的逻辑运算代码如下所示,主要是比较逻辑与“&”和短路与“&&”的运算结果:

		int i=1, j=1;
// 对于按位逻辑运算,需要等待左右两边都计算完毕,然后进行按位逻辑判断
boolean result1 = 3>4 & ++i<5;
System.out.println("result1="+result1);
System.out.println("i="+i);
// 对于短路逻辑运算,一旦左边的计算能够确定结果,就立即返回逻辑判断的值,此时不再进行右边的计算
boolean result2 = 3>4 && ++j<5;
System.out.println("result2="+result2);
System.out.println("j="+j);

运行以上示例代码,得到下述的运算日志:

result1=false
i=2
result2=false
j=1

可见两个逻辑式子的运算结果都为false,不同之处在于:“&”符号同时进行了左右两边的运算,所以i++执行之后i值变为2;而“&&”符号先进行左边运算,发现3>4为假,说明与运算肯定为假,此时整个式子直接返回假,不再执行右边的计算,于是j值仍然为1(j++未执行)。从该实验看到,短路逻辑运算名副其实,其效率高于按位逻辑运算,因而在实际开发过程中,更经常使用短路符号“&&”和“||”进行逻辑运算,很少使用单个的“&”和“|”。

Java开发笔记(十五)短路逻辑运算的优势的更多相关文章

  1. Java开发笔记(五十)几种开放性修饰符

    前面介绍子类继承父类的时候,提到了public(公共)和private(私有)两个修饰符,其中public表示它所修饰的实体是允许外部访问的:而private表示它所修饰的实体不允许外部访问,只能在当 ...

  2. Java开发笔记(五十二)对象的类型检查

    前面介绍了类的多态性,来自于鸡类的实例chicken,既能用来表达公鸡实例,也能用来表达母鸡实例.可是这导致了一个问题,假如在call方法内部需要手工判断输入参数属于公鸡实例还是母鸡实例,那该如何是好 ...

  3. Java开发笔记(五十四)内部类和嵌套类

    通常情况下,一个Java代码文件只定义一个类,即使两个类是父类与子类的关系,也要把它们拆成两个代码文件分别定义.可是有些事物相互之间密切联系,又不同于父子类的继承关系,比如一棵树会开很多花朵,这些花儿 ...

  4. Java开发笔记(五十五)关键字static的用法

    前面介绍嵌套类的时候讲到了关键字static,用static修饰类,该类就变成了嵌套类.从嵌套类的用法可知,其它地方访问嵌套类之时,无需动态创建外层类的实例,直接创建嵌套类的实例就行.其实static ...

  5. Java开发笔记(五十六)利用枚举类型实现高级常量

    前面介绍了联合利用final和static可实现常量的定义,该方式用于简单的常量倒还凑合,要是用于复杂的.安全性高的常量,那就力不从心了.例如以下几种情况,final结合static的方式便缺乏应对之 ...

  6. Java开发笔记(五十八)简单接口及其实现

    前面介绍了抽象方法及抽象类的用法,看似解决了不确定行为的方法定义,既然叫唤动作允许声明为抽象方法,那么飞翔.游泳也能声明为抽象方法,并且鸡类涵盖的物种不够多,最好把这些行为动作扩展到鸟类这个群体,于是 ...

  7. Java开发笔记(五十九)Java8之后的扩展接口

    前面介绍了接口的基本用法,有心的朋友可能注意到这么一句话“在Java8以前,接口内部的所有方法都必须是抽象方法”,如此说来,在Java8之后,接口的内部方法也可能不是抽象方法了吗?之所以Java8对接 ...

  8. Java开发笔记(五十一)多态的发生场景

    江湖上传闻,面向对象之所以厉害,是因为它拥有封装.继承与多态三项神技,只要三板斧一出,号令天下谁敢不从.前面费了老大的劲才讲清楚封装和继承,那么多态又是怎样的神乎其神呢?下面先通过一个简单的例子来说明 ...

  9. Java开发笔记(五十三)关键字final的用法

    前面介绍了多态的相关用法,可以看到一个子类从父类继承之后,便能假借父类的名义到处晃悠.这种机制在正常情况之下没啥问题,但有时为了预防意外发生,往往只接受当事人来处理,不希望它的儿子乃至孙子来瞎掺和.可 ...

  10. Java开发笔记(五十七)因抽象方法而产生的抽象类

    前面介绍了类的常见用法,令人感叹面向对象的强大,几乎日常生活中的所有事物,都可以抽象成Java的基类及其子类.然而抽象操作也有副作用,就是某个抽象而来的行为可能是不确定的,比如半夜鸡叫,如果是公鸡则必 ...

随机推荐

  1. Scala语言笔记 - 第一篇

    目录 Scala语言笔记 - 第一篇 1 基本类型和循环的使用 2 String相关 3 模式匹配相关 4 class相关 5 函数调用相关 Scala语言笔记 - 第一篇 ​ 最近研究了下scala ...

  2. java爬虫案例学习

    最近几天很无聊,学习了一下java的爬虫,写一些自己在做这个案例的过程中遇到的问题和一些体会1.学习目标         练习爬取京东的数据,图片+价格+标题等等 2.学习过程 1·开发工具      ...

  3. git 本地同步分支数,删除远程已经删除掉的多余分支

    git remote show orgin  (展示当前本地分支和远程上的分支差异,多余分支后会被标注 use 'git remote prune' to remove.) git remote pr ...

  4. 快速实现office文档在线预览展示(doc,docx,xls,xlsx,ppt,pptx)

    微软:https://view.officeapps.live.com/op/view.aspx?src=(输入你的文档在服务器中的地址):

  5. Java作业五(2017-10-15)

    /*3-6.程序员;龚猛*/ 1 package zhenshu; import java.util.Scanner; public class text { public static void m ...

  6. Docker常用命令(一)

    [转]原始出处:http://zxx287856774.blog.51cto.com/3417296/1665264 docker中 启动所有的容器命令 docker start $(docker p ...

  7. Windows10获取VS管理员权限总是很烦人

    之前在Windows 7中,只要关闭了UAC,给当前账户管理员权限,任何程序都会以管理员身份启动.现在,在Windows 10上就行不通了.而VS又需要管理员权限才能使用附加调试等一些功能.虽然我们可 ...

  8. SQL语句题

    SQL语句题 Student(Sno,Sname,Sage,Ssex)注释:学生表(学号,姓名,性别年龄,性别) Course(Cno,Cname,Tno) 注释:课程表(课程号,课程名称,教师编号) ...

  9. Echarts自定义tootips

    由于业务需求,现在要自定义tootips; 设计稿如下: 代码如下: app.title = '坐标轴刻度与标签对齐'; var str1 = "top:-20px;border:0px s ...

  10. FastDFS 学习笔记

      一.理论基础 FastDFS比较适合以中小文件为载体的在线服务,比如跟NGINX(APACHE)配合搭建图片服务器. 分布式文件系统FastDFS FastDFS是纯C语言实现,只支持Linux. ...