Java运算符优先级

所有的数学运算都认为是从左向右运算的,Java 语言中大部分运算符也是从左向右结合的,只有单目运算符、赋值运算符和三目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是从右向左运算。

乘法和加法是两个可结合的运算,也就是说,这两个运算符左右两边的操作数可以互换位置而不会影响结果。运算符有不同的优先级,所谓优先级就是在表达式运算中的运算顺序。

一般而言,单目运算符优先级较高,赋值运算符优先级较低。算术运算符优先级较高,关系和逻辑运算符优先级较低。多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。

Java 语言中运算符的优先级共分为 14 级,其中 1 级最高,14 级最低。在同一个表达式中运算符优先级高的先执行。表 1 列出了所有的运算符的优先级以及结合性。

表1 运算符的优先级
优先级 运算符 结合性
1 ()、[]、{} 从左向右
2 !、+、-、~、++、-- 从右向左
3 *、/、% 从左向右
4 +、- 从左向右
5 «、»、>>> 从左向右
6 <、<=、>、>=、instanceof 从左向右
7 ==、!= 从左向右
8 & 从左向右
9 ^ 从左向右
10 | 从左向右
11 && 从左向右
12 || 从左向右
13 ?: 从右向左
14 =、+=、-=、*=、/=、&=、|=、^=、~=、«=、»=、>>>= 从右向左

使用优先级为 1 的小括号可以改变其他运算符的优先级,即如果需要将具有较低优先级的运算符先运算,则可以使用小括号将该运算符和操作符括起来。例如下面的表达式:
(x-y)*z/5
在这个表达式中先进行括号内的减法运算,再将结果与 z 相乘,最后将积除以 5 得出结果。整个表达式的顺序按照从左向右执行,比较容易理解。

再来看一个复杂的表达式,如下所示。
--y || ++x && ++z;
这个表达式中包含了算术运算符和逻辑运算符。根据表 1 中列出的优先级,可以确定它的执行顺序如下:
① 先计算 y 的自减运算符,即 --y。
② 再计算 x 的自增运算符,即 ++x。
③ 接着计算 z 的自增运算符,即 ++z。
④ 由于逻辑与比逻辑或的优先级高,这里将 ② 和 ③ 的结果进行逻辑与运算,即 ++x && ++z。
⑤ 最后将 ④ 的结果与 ① 进行逻辑或运算,即 --y||++x&&++z。

如果没有上述对该表达式执行顺序的说明,第一眼看到它时将很难识别优先级。对于这类问题,可以通过添加小括号使表达的顺序更加清晰,而不用去查优先级表。如下所示为改进后的表达式。
(--y)||((++x)&&(++z));
技巧:记住这么多运算符的优先级是比较困难的,因此读者应该在实际应用中多多练习。

因为 Java 运算符存在这种优先级的关系,因此在做 SCJP 的时候或者某些公司的面试题,有如下 Java 代码:

int a = 5;
int b = 4;
int c = a++- --b*++a/b-- >>2%a--;

问 c 的值是多少?这样的语句实在太恐怖了,即使多年的老程序员看到这样的语句也会眩晕。这样的代码只能在考试中出现,作为一个程序员如果写这样的代码,恐怕他马上就得走人了,因为他完全不懂程序开发。

源代码就是一份文档,源代码的可读性比代码运行效率更重要。 因此在这里要提醒大家:
  • 不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。
  • 不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用()来控制表达式的执行顺序。

推荐文章
操作系统的I/O结构

存储器只是众多计算机I/O设备中的一种。操作系统的大部分代码专门用于I/O管理,这是由于它对系统的可靠性和性能至关重要,也是由于不同设备具有不同特性。因此,我们首先概述一下I/O。 每个通用计算机系

hub是什么?

hub(集线器)是指将多条以太网双绞线或光纤集合连接在同一段物理介质下的设备。集线器是运作在OSI模型中的物理层。它可以视作多端口的中继器,若它侦测到碰撞,它会提交阻塞信号。集线器的主要功能是对接收到

Apollo在Java中的使用

本节主要讲解在普通的Java项目和SpringBoot中如何使用Apollo。 普通Java项目中使用 加入ApolloClient的Maven依赖,代码如下所示。    com.ctrip.f

alt+f4的功能是什么?

“alt+f4”在windows操作系统中是一个热键/快捷键,主要功能是:1、用来关闭当前窗口;2、如所有窗口已关闭或最小化,则为关机快捷键,使用后会弹出一关机对话框。ALT+F4组合快捷键,用于利用

Django聚合查询和分组查询

聚合查询是指对一个数据表(Model)中某个字段的数据进行部分或者全部统计查询的一种方式,比如所有全部书的平均价格或者是书籍的总数量等等,在这些时候就会使用到聚合查询这种方法。而分组查询同样也属于聚合

Linux命令执行过程(新手必读)

前面讲过,在Linux系统中“一切皆文件”,Linux命令也不例外。那么,当编辑完成Linux命令并回车后,系统底层到底发生了什么事情呢? 简单来说,Linux命令的执行过程分为如下4个步骤。 1

建立JDBC连接

Connection对象代表与数据库的连接。连接过程包括所执行的SQL语句和在该连接上返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。 打开连接 与数据库建立连接的

c语言中指针有什么用?

一、什么是指针C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址。CPU通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里,数据对象是指存储在内存

usb-a接口和usb-c接口有什么区别?

首先,我们来了解一下USB-A与USB-C。什么是USB-A接口?USB“TypeA”连接是指USB端口的物理设计。每一个USB连接都是由主机设备的端口、连接电缆和接收器设备组成。USB-a是一个传统

Java Math类的常用方法

Java中的+、-、*、/和%等基本算术运算符不能进行更复杂的数学运算,例如,三角函数、对数运算、指数运算等。于是Java提供了Math工具类来完成这些复杂的运算。 在Java中Math类封装了常用

Linux pstree命令:查看进程树

pstree命令是以树形结构显示程序和进程之间的关系,此命令的基本格式如下: [root@localhost~]#pstree[选项][PID或用户名] 表1罗列出了pstree命令常用选项以及各自

C++ enum枚举用法攻略(超详细)

C++允许程序员创建自己的数据类型,比如本节要将的枚举类型。枚举数据类型是一种由程序员定义的数据类型,其合法值是与它们关联的一组命名整数常量。 之所以被称为枚举类型,就是因为命名常量是作为数据类型定

C++ includes(STL includes)算法详解

includes()算法可以比较两个元素的集合,如果第一个集合中的全部元素都来自第二个集合,它会返回true。如果第二个集合是空的集合,它也返回true。下面是一些示例: std::setword

Python rjust()字符串右对齐方法详解

和ljust()方法类似,不同之处在于,rjust()方法是向字符串的左侧填充指定字符,从而达到右对齐文本的目的。 rjust()方法的基本格式如下: S.rjust(width[,fillcha

Spring MVC拦截器(Interceptor)的配置及使用

在开发一个网站时可能有这样的需求:某些页面只希望几个特定的用户浏览。对于这样的访问权限控制,应该如何实现呢?拦截器就可以实现上述需求。在Struts2框架中,拦截器是其重要的组成部分,SpringMV

常用的9个网络命令是什么?

既然我们天天跟电脑打交道,多学习并且记下这些重要的命令十分有必要的。下面给大家讲讲常用的九个重要命令及这些命令的作用,一起来学习吧。1、ping命令ping是个使用频率极高的实用程序,主要用于确定网络

啥叫大数据?

大数据(bigdata),IT行业术语,是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信

甲壳虫2012年VIP之C++入门视频教程(22讲)

甲壳虫C++培训教程共22课时,包含课件以及源码,教学环境为WindowsXP,IED为VisualC++6.0。该课程侧重于C++基础。

jQuery事件是什么?

在之前的学习中,我们接触过鼠标点击事件,即click()。那事件究竟是什么呢?举个例子,当我们点击一个按钮时,会弹出一个对话框。其中“点击”就是一个事件,“弹出对话框”就是我们在点击这个事件里面做的一

什么是类,Python class类的定义

Python从设计之初就是一门面向对象的语言,Python中的一切数据都是对象。 Python中涉及面向对象的术语主要有: 类:用来描述具有相同的属性和方法的对象的集合,定义了该集合中每个对象所