# 第 4 节 Java运算符

***

所有的程序实际上都是对数字数据的处理，而在处理的过程中必然涉及到对数据的操作。在之前使用过这样的语法：

```java
int num = 10;
```

这种方式称为赋值运算符，“ = ”是实现赋值运算使用的。

进行数学计算时所使用的四则运算符也属于运算符号的定义范畴。由左至右

| 优先级 |      运算符      |     类     |  结合性 |
| :-: | :-----------: | :-------: | :--: |
|  1  |       ()      |   括号运算符   | 由左至右 |
|  1  |      \[]      |   方括号运算符  | 由左至右 |
|  2  | !、+（正号）、-（负号） |   一元运算符   | 由右至左 |
|  2  |       \~      |   位逻辑运算符  | 由右至左 |
|  2  |     ++、--     |  递增与递减运算符 | 由右至左 |
|  3  |     \*、/、%    |   算术运算符   | 由左至右 |
|  4  |      +、-      |   算术运算符   | 由左至右 |
|  5  |     >>、<<     | 位左移、右移运算符 | 由左至右 |
|  6  |   >、>=、<、<=   |   关系运算符   | 由左至右 |
|  7  |     ==、!=     |   关系运算符   | 由左至右 |
|  8  |   &（位运算符AND）  |   位逻辑运算符  | 由左至右 |
|  9  |   ^（位运算符XOR）  |   位逻辑运算符  | 由左至右 |
|  10 |   丨（位运算符OR）   |   位逻辑运算符  | 由左至右 |
|  11 |       &&      |   逻辑运算符   | 由左至右 |
|  12 |       丨丨      |   逻辑运算符   | 由左至右 |
|  13 |       ?:      |   三目运算符   | 由右至左 |
|  14 |       =       |   赋值运算符   | 由右至左 |

但是对于所有的运算符，切记不要编写过于复杂的操作。

如果对自己编写的运算顺序不是十分确定，就用“（）”来改变优先级，或者将操作拆开。

**范例：** 观察一种神奇的代码

```java
int numA = 10;
int numB = 20;
int result = numA * 2 - --numB * numA ++ + numB - numA -- + numB;
System.out.println(result);
```

以后写代码，一定要写出像“ 1 + 1 = 2”这样简单的代码，若果是真的复杂的代码，建议使用“ () ”改变优先级。

## 基本运算符

在开发中常用的几类运算符：四则运算符、逻辑运算、三目运算、位运算。

对于四则运算基本的组成是：+、-、\*、/、%。

**范例：** 四则运算

```java
int numA = 10;
int numB = 20;
System.out.println("加法计算" + (numA + numB));
System.out.println("减法计算" + (numA - numB));
System.out.println("乘法计算" + (numA * numB));
System.out.println("除法计算" + (numA / (double)numB));
System.out.println("加法计算" + (numA + numB));
```

**范例：** 求模计算

```java
int numA = 10;
int numB = 3;
System.out.println("求模计算" + (numA % numB));
```

在运算符里面又提供了一些简化运算符：\*=、/=、+=、-=、%=。

```java
int num = 10;
num *= 2; //num = num * 2;
System.out.println(num);
```

还有一类运算符是“ ++ ”（自增）、“ -- ”（自减），它根据位置不同，执行的顺序也不同。

* ++变量、--变量：写在前面表示的是进行内容的自增1或自减1之后再使用变量进行数学计算；
* 变量++、变量--：先使用变量内容进行计算，而后在实现自增或自减的操作。

\*\*范例；\*\*观察自增

```java
int numA = 10;
int numB = 20;
int result = ++ numA + numB;
System.out.println("numA = " + numA);
System.out.println("result = " + result);
```

```java
int numA = 10;
int numB = 20;
int result = numA ++ + numB;
System.out.println("numA = " + numA);
System.out.println("result = " + result);
```

如果以后使用此类的操作，也只会使用“ numA ++ ”；

## 三目运算符

三目是一种赋值运算的形式，执行三目的时候可以以一个布尔表达式的结果进行赋值，基本语法结构如下：

```
数据类型 变量 = 布尔表达式 ? 满足此表达式时设置的内容 : 不满足此表达式时设置的内容;
```

**范例：** 实现赋值

```java
int numA = 10;
int numB = 20;
//如果numA大于numB，返回true，则将numA的内容赋值给max
//如果numA小于numB，返回false，则将numB的内容赋值给max
int max = numA > numB ? numA : numB;
System.out.println(max);
```

如果此处不使用三目运算，则就需要编写如下形式的判断语句完成了。

```java
int numA = 10;
int numB = 20;
int max = 0;
if (numA > numB) {
    max = numA;
} else {
    max = numB;
}
System.out.println(max);
```

利用三目可以节约一些判断代码。

三目运算还可以进行嵌套。

```
int numA = 10;
int numB = 20;
int flag = numA > numB ? 1 : (numA < numB ? -1 : 0);
```

但是这种操作会让程序的可读性变得很差。

## 逻辑运算

对于逻辑运算主要就是：与（&、&&）、或（|、||）、非（！）三种计算。

**范例：** 非就是针对布尔类型进行求反

```java
boolean flag = true;
System.out.println(!flag);
```

如果现在是多个布尔表达式想要进行连接，只能够使用与和或两个操作。

**1. 与操作**

**范例：** 观察普通与“ & ”

```java
if ((1 == 2) & (10 / 0 == 0)) {
    System.out.println("Hello World !");
}
```

此时使用的是一个“ & ”，发现第一个判断返回false之后第二个判断（(10 / 0 == 0)）继续执行，但是现在的问题是，如果前面的条件已经返回了false，后面不管有多少个true，最终的结果还是false，那么完全没有必要进行后面的判断。

**范例：** 使用短路与（&&）

```java
if ((1 == 2) & (10 / 0 == 0)) {
    System.out.println("Hello World !");
}
```

此时没有出错，因为前面的条件返回了false，后面就自然不需要判断。

**2. 或操作**

**范例：** 观察普通或（|）

```java
if ((1 == 1) | (10 / 0 == 0)) {
    System.out.println("Hello World !");
}
```

使用普通或的时候所有的判断条件都进行了执行，但是或运算的基本形式是：只要有一个判断返回了true，后面不管有多少个true或者是false，最终的结果永远都是true。

**范例：** 观察短路或（&&）

```java
if ((1 == 1) || (10 / 0 == 0)) {
    System.out.println("Hello World !");
}
```

从此以后就是用短路与和短路或操作。

> 除了以上三种操作之外还有一种不常用的逻辑运算操作称为**异或(^)** 异或有着较为特殊的性质：当运算符两侧布尔值相同是结果为false，两侧布尔值不同时结果为true；
>
> ```java
> System.out.println(true ^ true);    // false
> System.out.println(true ^ false);   // true
> System.out.println(false ^ true);   // true
> System.out.println(false ^ false);  // false
> ```
>
> 异或操作一般用于数据加密算法的实现

## 位运算（了解）

在之前所进行的数学都使用的是十进制数据，而Java本身的运算支持二进制、八进制、十六进制。下面重点观察二进制，如果想要将十进制变为二进制的形式，采用的是短除法（除2、取余、倒序）。

位运算主要是进行二进制数据操作的，可以使用：&、|、>>、<<、^、\~。

**范例：** 实现位与操作

```java
int numA = 9;
int numB = 11;
System.out.println(numA & numB);
```

9 的二进制：00000000 00000000 00000000 00001001 11的二进制：00000000 00000000 00000000 00001011 & 结果：00000000 00000000 00000000 00001001

**范例：** 实现位或操作

```java
int numA = 9;
int numB = 11;
System.out.println(numA | numB);
```

9 的二进制：00000000 00000000 00000000 00001001 11的二进制：00000000 00000000 00000000 00001011 | 结果：00000000 00000000 00000000 00001011

**范例：** 移位操作（请用最快的方式计算2的3次方结果）

```java
int num = 2;
int result = num << 2;
System.out.println(num);
System.out.println(result);
```

2 的二进制：00000000 00000000 00000000 00000010 左移位之后：00000000 00000000 00000000 00001000

\*\*面试题：\*\*请解释“ & ”和“ && ”的区别？“ | ”和“ || ”的区别？

* 逻辑运算：
  * 与运算分为普通与（&）和短路与（&&）两种；
    * 普通与：所有的判断条件都要判断；
    * 短路与：如果前面的判断返回了false，后面不再判断，结果就是false。
  * 或运算分为普通或（|）和短路或（||）两种；
    * 普通或：所有的判断条件都要判断；
    * 短路或：如果前面的判断返回了true，后面不在判断，结果就是true。
* 位运算：位与运算（&）、位或运算（|），其中“ && ”和“ || ”不能运用在位运算上。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shepherd-xie.gitbook.io/be-a-javaer/di-1-zhang-java-bian-cheng-kai-fa-ru-men/section-4.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
