当前位置: 首页 > news >正文

第二章 变量和运算符

主要内容

  1. 关键字和标识符
  2. 变量和常量
  3. 八大基本数据类型
  4. Scanner键盘输入
  5. 基本数据类型的类型转换
  6. 算术运算符
  7. 赋值运算符
  8. 扩展赋值运算符
  9. 比较运算符
  10. 逻辑运算符
  11. 三目运算符
  12. 运算符的优先级别

学习目标

知识点要求
关键字和标识符理解
变量和常量掌握
八大基本数据类型掌握
Scanner键盘输入 掌握
基本数据类型的类型转换掌握
算术运算符掌握
赋值运算符掌握
扩展赋值运算符掌握
比较运算符掌握
逻辑运算符掌握
三目运算符掌握
运算符的优先级别了解

1.常量和变量

1.1 关键字&保留字

Java关键字是编程语言中预先定义、具有特定含义的标识符,也称为保留字。这些关键字对Java编译器具有特殊意义,用于表示数据类型或程序结构等核心功能。

abstractbooleanbreakbytecase
catchcharclassconstcontinue
defaultdodoubleelseenum
extendsfinalfinallyfloatfor
gotoifimplementsimportinstanceof
intinterfacelongnativenew
packageprivateprotectedpublicreturn
shortstaticstrictfpsuperswitch
synchronizedthisthrowthrowstransient
tryvoidvolatilewhile

备注:这些关键字不需要刻意去背,后面会慢慢介绍每个关键字的用法。

1.2 标识符

在Java编程中,标识符是用于为变量、类、方法及包等程序元素命名的命名符号。

1.2.1 标识符命名规则

  • 标识符由字母(A-Z 和 a-z)、数字(0-9)、下划线(_)和美元符号($)构成;
  • 标识符的首字符不能为数字,后续部分可包含字母、下划线、美元符号和数字的任意组合;
  • Java 标识符区分大小写,且长度不受限制;
  • 标识符不得使用 Java 关键字和保留字。

1.2.2 标识符命名规范

  • 类名标识符应采用大驼峰式命名法(PascalCase),即首字母大写且每个单词首字母大写。
    例如:Person、GoodStudent
  • 方法和变量标识符应采用小驼峰式命名法(camelCase),即首字母小写且后续单词首字母大写。
    例如:int userName;、public void eatFood(){}

特别说明:由于Java采用Unicode字符集,标识符可使用包括中文在内的多种字符。但为提高代码可读性和维护性,建议避免使用汉字作为标识符。

1.3 变量(Variable)

1.3.1 变量的本质

变量本质上是一个具有确定存储位置的可操作空间,其具体存储值则是不确定的。通过变量名,我们可以访问并操作该存储空间中的内容。

Java作为一门强类型语言,要求所有变量在使用前必须明确声明其数据类型。这种数据类型不仅决定了变量所能存储的值的范围,还直接影响了变量在内存中所占用的存储空间大小。我们可以将内存中的变量形象地比作旅馆的房间,而常量则如同入住这些房间的旅客,每个房间(变量)都有其特定的类型和容量,用于容纳不同类型的旅客(常量)。
在这里插入图片描述

1.3.2 变量的声明

变量声明语法:数据类型 变量名;
变量声明本质:就是在内存中开辟一块内存空间,用于存放指定数据类型的数据。

  • 声明一个变量
/*** @Author: chenxiezhu* @Date: 2025/5/12 23:08* @Version: v1.0.0* @Description: TODO**/
public class VariableDemo1 {public static void main(String[] args) {// 定义整型变量ageint age;// 定义双精度浮点型变量pricedouble price;}
}
  • 同时声明多个变量

语法:数据类型 变量名1, 变量名2, 变量名3;

/*** @Author: chenxiezhu* @Date: 2025/5/12 23:08* @Version: v1.0.0* @Description: TODO**/
public class VariableDemo1 {public static void main(String[] args) {// 声明一个int类型的变量ageint age;// 声明一个float类型的变量double price;// 声明多个int类型的变量int num1, num2, num3;}
}

注意:在同时声明多个变量时,所有变量必须属于同一类型。

1.3.3 变量的赋值

变量赋值的本质是:通过变量名定位对应的内存地址,并将数据存储到该内存区域中。

  • 给变量赋值
/*** @Author: chenxiezhu* @Date: 2025/5/12 23:20* @Version: v1.0.0* @Description: TODO**/
public class VariableDemo2 {public static void main(String[] args) {// 声明一个int类型的变量ageint age; // 在内存中分配存储空间// 为age变量赋值age = 23; // 将等号右侧的值赋给左侧的变量}
}

注意:赋值的数据类型必须和声明变量类型一致。

  • 声明和赋值同时进行

语法: 数据类型 变量名 = 数据值;

/*** @Author: chenxiezhu* @Date: 2025/5/12 23:20* @Version: v1.0.0* @Description: TODO**/
public class VariableDemo2 {public static void main(String[] args) {int age2 = 23; // 将右侧的值赋给左侧变量}
}
  • 同时声明和赋值多个变量

语法:数据类型 变量名1 = 数据值1,变量名2 = 数据值2,变量名3 = 数据值3;

/*** @Author: chenxiezhu* @Date: 2025/5/12 23:20* @Version: v1.0.0* @Description: TODO**/
public class VariableDemo2 {public static void main(String[] args) {// 一次性声明并初始化多个变量(不推荐,影响代码可读性)int num1 = 10, num2 = 20, num3 = 30;}
}

1.3.4 变量总结和提升

变量以"变"为核心特征,其本质在于声明时开辟的内存空间可被重复赋值。

使用变量时需注意以下要点:

1)方法内部声明的变量必须在赋值后才能调用;
2)变量使用需遵循声明优先原则,未经声明的变量名不具备任何意义;
3)命名规范要求变量名采用小写字母开头的驼峰式命名法,且必须符合标识符规则;
4)赋值操作需确保数据类型与变量声明类型严格一致;
5)同一方法内禁止声明多个同名变量。

1.4 常量(Constant)

在编程中,常量指代不可变的固定值,常见示例包括:整型1、浮点型2.1、字符’a’、布尔值true/false、字符串"helloWorld"、空字符串""以及空值null等。

在Java语言中,我们可以通过final关键字来显式声明常量。

语法:final 数据类型 常量名 = 数据值;

常量的核心特性在于其不可变性:一旦完成初始化赋值,其值将始终保持不变,无法被后续程序修改。

/*** @Author: chenxiezhu* @Date: 2025/5/12 23:37* @Version: v1.0.0* @Description: TODO**/
public class ConstantDemo1 {public static void main(String[] args) {final float PI = 3.1415926f;}
}

注意:

  1. 常量仅允许赋值一次,一旦赋值完成,其值便不可修改。
  2. 常量名称通常采用大写字母,多个单词之间以下划线分隔,例如:final int MAX_VALUE = 100;

2. 基本数据类型

Java 作为一门强类型语言,要求所有变量在使用前必须明确声明其数据类型。
Java 的数据类型主要分为两大类:基本类型(Primitive Type)和引用类型(Reference Type)。

在这里插入图片描述

2.1 整数型

整数型常量可分为以下三种表示形式:

  • 十进制整数,如:666,-100等
  • 八进制整数,要求以0开头,如:016
  • 十六进制整数,要求以0x或0X开头,如:0x1A,0x15

数据类型占用存储空间越大,那么表数的范围也就越大。在开发实践中,应根据具体需求选择合适的数值类型,避免超出表数范围。通常情况下,int类型是最常用的选择。

类型占用存储空间数值范围
byte1 字节(-128 ~ 127)
-27~ 27 - 1
short2 字节(-32768 ~ 32767)
-215 ~ 215 - 1
int4 字节(-2147483648 ~ 2147483647) 约 21 亿
-231 ~ 231 - 1
long8 字节-263~ 263 - 1

注意:

  1. 需特别关注数据类型的数值范围,防止因超出范围导致精度损失。
  2. 整型常量默认采用int类型,如需声明long型常量,可在数值后添加"l"或"L",推荐使用"L"以增强可读性。

2.2 浮点型

在Java中,小数类型统称为浮点类型。
浮点型常量有两种表示形式:

  1. 十进制形式,如:3.14 或 123.45
  2. 科学计数法形式,如:314E2(表示31400.0)或314E-2(表示3.14)

浮点类型主要分为两种:

  1. float(单精度)类型:可精确到7位有效数字,但在多数场景下其精度难以满足需求。
  2. double(双精度)类型:其数值精度是float类型的两倍,是大多数应用程序的首选。需要注意的是,Java中的浮点型常量默认采用double类型。
类型占用存储空间数值范围
float4字节-3.403E38 ~ 3.403E38
double8字节-1.798E308 ~ 1.798E308

使用浮点型常量时需注意以下事项:

  1. 浮点型常量默认采用 double 类型存储
  2. 将浮点型常量赋值给 float 类型变量时,需在常量后添加后缀 “f” 或 “F”
  3. 不建议直接比较两个浮点数的大小,这种比较方式可能导致精度问题

扩展知识:
整数和浮点数在内存中的存储机制存在显著差异,建议对此感兴趣的同学可以进一步查阅相关资料深入了解。

2.3 布尔型

boolean(布尔型)包含两个取值:true(真)和false(假)。它主要用于逻辑判断,是程序流程控制中的核心数据类型。

扩展知识:
根据Java语言规范,boolean类型的具体存储空间并未明确规定。如需深入了解,建议查阅相关技术文档。

2.4 字符型

2.4.1 字符型

在Java中,字符型数据占用2个字节的内存空间。使用单引号括起来的单个字符被称为字符常量。
如:'A’表示一个字符常量,而"A"则表示一个仅包含单个字符的字符串,两者在Java中具有不同的数据类型和存储方式。

【示例】字符型使用

/*** @Author: chenxiezhu* @Date: 2025/5/13 19:37* @Version: v1.0.0* @Description: TODO**/
public class CharDemo1 {public static void main(String[] args) {char ch1 = 'c';  // 正确:声明并赋值字符'c'char ch2 = '好'; // 正确:声明并赋值字符'好'char ch3 = '6';  // 正确:声明并赋值字符'6'char ch4 = '66'; // 错误:单引号内只能包含单个字符char ch5 = '';   // 错误:单引号内必须包含一个字符char ch6 = "你"; // 错误:字符必须使用单引号,双引号用于字符串}
}

IDEA 会自动检测并提示代码中的错误。
在这里插入图片描述
补充说明:char类型用于表示Unicode编码表中的字符,因此它能够完整地表示一个中文字符。

  • char类型和int类型的联系和区别

char类型常量在内存中直接存储其对应的Unicode编码值,例如:字符’A’对应65,字符’1’对应49。在特定取值范围内,char类型与int类型可以相互转换并通用。

【示例】char类型和int类型

/*** @Author: chenxiezhu* @Date: 2025/5/13 19:51* @Version: v1.0.0* @Description: TODO**/
public class CharDemo2 {public static void main(String[] args) {char ch1 = 'C'; // Unicode对应的数值为65System.out.println(ch1 + 1);          // 输出:68char ch2 = 99;  // Unicode对应的字符为'c'System.out.println((char)(ch2 - 32)); // 输出:'C'}
}

在这里插入图片描述
char类型与int类型的主要区别:

  1. 内存占用差异:nt类型在内存中占用4个字节,而char类型仅占用2个字节。
  2. 数值范围不同:int类型能够表示的数值范围远大于char类型,此外,int类型支持表示负数,而char类型通常用于表示字符或较小的非负整数。

2.4.2 字符集

计算机系统仅能识别0和1,所有信息都以二进制形式存储。对于数值型数据,我们可以直接将其转换为二进制并存入内存,那么字符型数据是如何存储的呢?

实际上,字符本身无法直接转换为二进制。我们在屏幕上看到的英文字母、汉字等字符,都是经过二进制转换后的结果。简单来说,将字符存储在计算机中的规则被称为"编码"。例如,字符’A’可以用十进制数65表示,然后将65转换为二进制存储在内存中。

相反,将计算机中存储的二进制数解析并显示出来的过程称为"解码"。例如,当我们从内存中读取数值65时,就表示读取的字符是’A’。

基于这种"编码"和"解码"机制,人类为不同语言创建了相应的编码表。

以下是几种常见的字符编码表

  1. ASCII:美国信息交换标准代码,基于拉丁字母的计算机编码系统,主要用于显示现代英语和西欧语言。
  2. GBK:全称《汉字内码扩展规范》,是用于表示中文的编码标准。
  3. Unicode:又称万国码或统一码,旨在解决传统编码方案的局限性。它为每种语言的每个字符设定了统一且唯一的二进制编码,满足跨语言、跨平台的文本转换和处理需求。

Unicode编码占用2个字节,可表示65536个字符,一个中文字符在内存中占用2个字节。

2.4.3 转义字符

Java 语言支持使用转义字符来改变后续字符的特定含义。

转义符含义Unicode值
\n换行符\u000a
\t制表符\u0009
\"双引号\u0022
\'单引号\u0027
\\反斜杠\u005c

3. Scanner键盘输入

Scanner类位于java.util包中,是Java 5引入的一个用于获取用户输入的类。它提供了读取不同类型数据的便捷方法,大大简化了控制台输入的处理过程。

3.1 导入Scanner包

通过在源文件开头导入java.util.Scanner包,我们便可以在代码中直接使用Scanner类。

import java.util.Scanner;

3.2 初始化Scanner对象

Scanner input = new Scanner(System.in);

3.3 获取输入的数据

从控制台读取用户输入的一行文本,并将其转换为指定类型的数据。

String str = input.next();  // 获取控制台输入的字符串

【示例】

import java.util.Scanner;/*** @Author: chenxiezhu* @Date: 2025/5/14 22:17* @Version: v1.0.0* @Description: TODO**/
public class ScannerDemo {public static void main(String[] args) {// 创建Scanner对象,从标准输入(键盘)获取数据Scanner input = new Scanner(System.in);// 使用Scanner对象的方法读取输入System.out.println("请输入一个字符串:");String number = input.next();System.out.println("您输入的字符串是:" + number);// 关闭Scanner对象input.close();}
}

在这里插入图片描述

3.4 Scanner类的常用方法

Scanner提供了多种读取不同数据类型的方法:

方法描述示例
nextInt()读取一个整数int num = input.nextInt()
nextDouble()读取一个双精度浮点数double d = input.nextDouble()
nextFloat()读取一个单精度浮点数float f = input.nextFloat()
nextLong()读取一个长整型数long l = input.nextLong()
nextBoolean()读取一个布尔值boolean b = input.nextBoolean()
next()读取一个字符串,遇到空白字符结束String s = input.next()
nextLine()读取一整行文本,遇到换行符结束String line = input.nextLine()
hasNext()判断是否还有下一个输入(任意类型)while(input.hasNext()) {...}
hasNextInt()判断下一个输入是否为整数if(input.hasNextInt()) {...}
hasNextLine()判断是否还有下一行while(input.hasNextLine()) {...}

【示例】

import java.util.Scanner;/*** @Author: chenxiezhu* @Date: 2025/5/14 22:23* @Version: v1.0.0* @Description: TODO**/public class ScannerTypeDemo {public static void main(String[] args) {Scanner input = new Scanner(System.in);// 读取整数System.out.println("请输入您的年龄:");int age = input.nextInt();// 读取浮点数System.out.println("请输入您的身高(米):");double height = input.nextDouble();// 读取一个单词(遇到空格停止)System.out.println("请输入您的名字:");input.nextLine(); // 处理换行符String firstName = input.next();// 读取一整行System.out.println("请输入您的全名:");input.nextLine(); // 处理上一个next()方法留下的换行符String fullName = input.nextLine();// 读取布尔值System.out.println("您是否为学生?(true/false)");boolean isStudent = input.nextBoolean();// 输出所有读取的信息System.out.println("\n您输入的信息如下:");System.out.println("年龄:" + age);System.out.println("身高:" + height + "米");System.out.println("名字:" + firstName);System.out.println("全名:" + fullName);System.out.println("是否为学生:" + isStudent);input.close();}
}

在这里插入图片描述

【注意事项】

  1. 调用数据获取方法时,程序将阻塞等待用户输入并按下回车键后才会继续执行后续代码。
  2. Scanner类未提供直接获取单个字符的方法,即不存在nextChar()方法。

【随堂练习】

  1. 编写一个程序,通过键盘输入获取矩形的长和宽,并计算该矩形的周长和面积。

4. 基本数据类型转换

在进行赋值或算术运算时,操作数的数据类型必须一致,否则需要进行类型转换。类型转换主要分为两种方式:

  1. 自动类型转换(隐式)
  2. 强制类型转换(显示)

基本数据类型之间的转换涉及以下类型:byte、short、int、long、float、double和char,其中boolean类型不参与此类转换。

4.1 自动类型转换

自动类型转换(隐式类型转换)是指当数据从较小容量的数据类型向较大容量的数据类型转换时,系统会自动完成这一过程。

  • 由低字节向高字节的转换 byte->short-> char –>int->long->float->double

【赋值运算中的类型转换案例】

/*** @Author: chenxiezhu* @Date: 2025/5/13 21:47* @Version: v1.0.0* @Description: TODO**/
public class TypeCastingDemo1 {public static void main(String[] args) {// 将int类型的值赋值给double数据类型(符合低字节向高字节自动转换)double num = 66;// 将整数常量赋值给byte、 short和char类型变量(不符合低字节向高字节转换)byte b = 110;short s = 119;byte by = 1234; // 编译错误:整数常量超出byte类型的取值范围}
}

将int类型的整型常量赋值给byte、short和char类型变量时,属于自动类型转换的特殊情况,只要该常量的值不超过目标类型的取值范围即可完成赋值。

IDEA提示错误,我们可以点击更多操作(Alt+Enter)修改或者手动修改

在这里插入图片描述
在这里插入图片描述

算术运算中的类型自动转换原则

  • 如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型,结果为double类型。
  • 否则,如果其中一个操作数是float类型,另一个将会转换为float类型,结果为float类型。
  • 否则,如果其中一个操作数是long类型,另一个会转换为long类型,结果为long类型。
  • 否则,两个操作数都转换为int类型,结果为int类型。

【算术运算中的类型转换案例】

/*** @Author: chenxiezhu* @Date: 2025/5/13 22:39* @Version: v1.0.0* @Description: TODO**/
public class TypePromotionExample {public static void main(String[] args) {// 如果其中一个操作数是double类型,结果是double类型double a = 5.5;int b = 3;double result1 = a + b; // b自动提升为double类型System.out.println("double类型 + int类型的结果:" + result1);// 如果其中一个操作数是float类型,结果是float类型float c = 4.2f;short d = 2;float result2 = c * d; // d自动提升为float类型System.out.println("float类型 * short类型的结果:" + result2);// 如果其中一个操作数是long类型,结果是long类型long e = 1000L;byte f = 10;long result3 = e - f; // f自动提升为long类型System.out.println("long类型 - byte类型的结果: " + result3);// 否则,两个操作数都转换为int类型,结果是int类型char g = 'A'; // ASCII值为65char h = 'B'; // ASCII值为66int result4 = g + h; // g和h自动提升为int类型System.out.println("char类型 + char类型的结果: " + result4);}
}

在这里插入图片描述

【常见面试题】

  1. byte b1 = 11; byte b2 = 12;byte sum = b1 + b2; 和int num1 = 100; int num2 = 300; int sum = num1 + num2;哪一个正确呢?
  2. 请问说出100000L100000100000和100000100000100000的区别?
  3. int num1 = 90000; int num2 = 90000; int total = num1 * num2; 请问total的结果是多少?

4.2 强制类型转换

强制类型转换(显示类型转换),主要用于显式的转换一个数值的类型。在有可能丢失信息的情况下进行的转换是通过造型来完成的,但可能造成精度降低或溢出。

语法格式:目标类型 变量 =(目标类型)源类型变量或常量

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/13 23:26* @Version: v1.0.0* @Description: TODO**/
public class TypeCastExample {public static void main(String[] args) {// 1. 精度损失示例double d = 3.99;int i = (int)d;  // 小数部分会被截断System.out.println("将3.99转为int: " + i);  // 输出: 3// 2. 数据溢出示例long bigNum = 3000000000L;int smallNum = (int)bigNum;  // 超出int范围会溢出System.out.println("将超大long转为int: " + smallNum);  // 输出可能是负数// 3. 数据截断示例byte b = (byte)130;  // byte范围是-128到127System.out.println("将130转为byte: " + b);  // 输出: -126// 4. 字符转换示例char ch = 'A';int ascii = ch;      // 自动类型转换char back = (char)ascii;  // 显式类型转换System.out.println("字符A的ASCII值: " + ascii);System.out.println("ASCII值65转回字符: " + back);}
}

在这里插入图片描述
使用强制类型转换的时候,一定要明确需要强转的数据。

5. 运算符(operator)

5.1 算术运算符

5.1.1 二元运算符

二元运算符是指需要两个操作数进行运算的运算符,包括加(+)、减(-)、乘(*)、除(/)和取模(%)。

运算符名称功能描述
+计算两个数的和
-计算两个数的差
*计算两个数的积
/计算两个数的商
%取模计算两个数相除的余数

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/14 16:12* @Version: v1.0.0* @Description: TODO**/
public class BinaryOperatorExample {public static void main(String[] args) {
// 定义测试用的变量int a = 10;int b = 3;double x = 10.5;double y = 3.2;// 1. 加法运算符 (+)int sum1 = a + b;double sum2 = x + y;String str1 = "Hello ";String str2 = "World";String strSum = str1 + str2;  // 字符串连接System.out.println("加法示例:");System.out.println("整数相加:10 + 3 = " + sum1);System.out.println("小数相加:10.5 + 3.2 = " + sum2);System.out.println("字符串连接:" + strSum);// 2. 减法运算符 (-)int diff1 = a - b;double diff2 = x - y;System.out.println("\n减法示例:");System.out.println("整数相减:10 - 3 = " + diff1);System.out.println("小数相减:10.5 - 3.2 = " + diff2);// 3. 乘法运算符 (*)int product1 = a * b;double product2 = x * y;System.out.println("\n乘法示例:");System.out.println("整数相乘:10 * 3 = " + product1);System.out.println("小数相乘:10.5 * 3.2 = " + product2);// 4. 除法运算符 (/)int quotient1 = a / b;    // 整数除法double quotient2 = x / y; // 浮点数除法double quotient3 = (double)a / b; // 整数转换为浮点数后除法System.out.println("\n除法示例:");System.out.println("整数相除:10 / 3 = " + quotient1);  // 结果为3(向下取整)System.out.println("小数相除:10.5 / 3.2 = " + quotient2);System.out.println("整数转浮点除法:10.0 / 3 = " + quotient3);// 5. 取模运算符 (%)int remainder1 = a % b;double remainder2 = x % y;System.out.println("\n取模示例:");System.out.println("整数取模:10 % 3 = " + remainder1);  // 余数为1System.out.println("小数取模:10.5 % 3.2 = " + remainder2);// 特殊情况示例System.out.println("\n特殊情况示例:");System.out.println("负数取模:-10 % 3 = " + (-10 % 3));  // 负数取模System.out.println("零除:10 / 0.0 = " + (10.0 / 0.0));  // 浮点数除以0try {System.out.println(a / 0);  // 整数除以0会抛出异常} catch (ArithmeticException e) {System.out.println("整数除以0会抛出异常:" + e.getMessage());}}
}

在这里插入图片描述

【注意事项】

  1. 加号(+)具有多重功能:既可用于加法运算,也可作为正号或字符串连接符。
  2. 当两个整数进行除法(/)运算时,结果将自动取整,仅保留整数部分,要得到精确结果,至少需要一个操作数是浮点数。
  3. 取模运算符(%)可用于整数和浮点数,结果的符号与被除数相同。
  4. 特殊情况:整数除以0会抛出ArithmeticException异常(异常我们后面再讲),浮点数除以0.0会得到Infinity或NaN,负数的取模运算结果的符号遵循特定规则。

【随堂练习】

  1. 获取整数2345的千位数、百位数、十位数和个位数。

5.1.2 一元运算符

仅需单个操作数的运算符被称为一元运算符,例如自增运算符(++)和自减运算符( --)等。

运算符名称等价形式运算顺序说明
++num前置自增num = num + 1先自增,后使用新值参与运算
num++后置自增num = num + 1先使用原值参与运算,后自增
--num前置自减num = num - 1先自减,后使用新值参与运算
num--后置自减num = num - 1先使用原值参与运算,后自减

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/14 16:36* @Version: v1.0.0* @Description: TODO**/
public class UnaryOperatorExample {public static void main(String[] args) {// 1. 前置自增运算符 (++num)System.out.println("1. 前置自增运算符示例:");int a = 5;int b = ++a;  // 先自增,再赋值System.out.println("a = " + a);    // 输出:6System.out.println("b = " + b);    // 输出:6// 2. 后置自增运算符 (num++)System.out.println("\n2. 后置自增运算符示例:");int c = 5;int d = c++;  // 先赋值,再自增System.out.println("c = " + c);    // 输出:6System.out.println("d = " + d);    // 输出:5// 3. 前置自减运算符 (--num)System.out.println("\n3. 前置自减运算符示例:");int e = 5;int f = --e;  // 先自减,再赋值System.out.println("e = " + e);    // 输出:4System.out.println("f = " + f);    // 输出:4// 4. 后置自减运算符 (num--)System.out.println("\n4. 后置自减运算符示例:");int g = 5;int h = g--;  // 先赋值,再自减System.out.println("g = " + g);    // 输出:4System.out.println("h = " + h);    // 输出:5// 5. 在表达式中使用System.out.println("\n5. 在表达式中的使用示例:");int i = 10;System.out.println("输出 ++i * 2: " + (++i * 2));  // 输出:22 (11*2)System.out.println("此时 i 的值: " + i);           // 输出:11int j = 10;System.out.println("输出 j++ * 2: " + (j++ * 2));  // 输出:20 (10*2)System.out.println("此时 j 的值: " + j);           // 输出:11// 6. 在循环中的使用System.out.println("\n6. 在循环中的使用示例:");System.out.print("使用前置自增的循环:");for(int k = 0; k < 3; ++k) {System.out.print(k + " ");}System.out.print("\n使用后置自增的循环:");for(int k = 0; k < 3; k++) {System.out.print(k + " ");}// 7. 连续使用自增/自减System.out.println("\n\n7. 连续使用自增/自减示例:");int m = 5;int n = ++m + m++ + --m + m--;System.out.println("m = " + m);    // 输出:5System.out.println("n = " + n);    // 输出:24// 计算过程:// ++m: m变为6,表达式值为6// m++: 使用6,m变为7,表达式值为6// --m: m变为6,表达式值为6// m--: 使用6,m变为5,表达式值为6// 最终:6 + 6 + 6 + 6 = 24}
}

在这里插入图片描述

【建议】

  • 在独立语句中,前置和后置运算符效果相同
  • 在表达式中使用时要特别注意运算顺序
  • 不建议在同一个表达式中多次使用自增/自减运算符,可能导致代码难以理解
  • 在循环中,前置和后置的性能差异通常可以忽略不计
  • 为了代码清晰度,建议在简单场景(如循环)中使用
  • 复杂表达式中应避免使用,改用更清晰的写法

【思考】

  1. 可以对常量进行递增或递减操作吗?例如:5++或++5。
  2. int num = 5; num = num++;请问代码执行后num的值为多少?

【随堂练习】

  1. int x = 7, y = 10; 求 x++ * 3 - --y + y++ / 2 + x-- % 5 - ++y * 2 的值。

5.2 赋值运算符

= 把等号右边的值赋值给左边(一直在用)

【随堂练习】

  1. 交换两个变量的值(用两种方式实现)。

5.3 扩展赋值运算符

扩展赋值运算符是算术运算符与赋值运算符的组合形式。

运算符用法举例等效的表达式
+=a += ba = a + b
-=a -= ba = a - b
*=a *= ba = a * b
/=a /= ba = a / b
%=a %= ba = a % b

【示例】

//1. 加法赋值运算符 +=
int b = 3;
b += 2; // 等价于 b = b + 2
System.out.println("b = " + b); // 输出: b = 5//2. 减法赋值运算符 -=
int c = 10;
c -= 4; // 等价于 c = c - 4
System.out.println("c = " + c); // 输出: c = 6//3. 乘法赋值运算符 *=
int d = 4;
d *= 3; // 等价于 d = d * 3
System.out.println("d = " + d); // 输出: d = 12//4.除法赋值运算符 /=
int e = 20;
e /= 5; // 等价于 e = e / 5
System.out.println("e = " + e); // 输出: e = 4//. 取模赋值运算符 %=
int f = 17;
f %= 5; // 等价于 f = f % 5
System.out.println("f = " + f); // 输出: f = 2

【随堂练习】

  1. 获取三个学生的成绩,并计算三个学生成绩的平均分。

【常见面试题】

  1. short num = 11; num = num + 1; 和short num = 11; num += 1;哪一个正确呢?
  2. int sum += 30; 请问这行语句语法是否正确???

5.4 比较运算符

比较运算符用来进行比较运算,比较运算符的运算结果是boolean类型。

运算符名称示例
>大于a > b
<小于a < b
>=大于或等于a >= b
<=小于或等于a <= b
==等于a == b
!=不等于a != b

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/14 17:10* @Version: v1.0.0* @Description: TODO**/
public class ComparisonOperators {public static void main(String[] args) {int a = 10;int b = 5;// 大于 >boolean result1 = a > b;System.out.println("a > b: " + result1);  // 输出: true// 小于 <boolean result2 = a < b;System.out.println("a < b: " + result2);  // 输出: false// 大于或等于 >=boolean result3 = a >= 10;System.out.println("a >= 10: " + result3);  // 输出: true// 小于或等于 <=boolean result4 = b <= 5;System.out.println("b <= 5: " + result4);  // 输出: true// 等于 ==boolean result5 = a == b;System.out.println("a == b: " + result5);  // 输出: false// 不等于 !=boolean result6 = a != b;System.out.println("a != b: " + result6);  // 输出: true// 实际应用示例int score = 85;if (score >= 60) {System.out.println("及格");  // 会输出这行} else {System.out.println("不及格");}}
}

在这里插入图片描述

5.5 逻辑运算符

参与逻辑运算的数据类型必须为boolean类型,逻辑运算后的结果也为boolean类型。

5.5.1 与运算、或运算、异或、非运算

运算符名称运算特点(输入→输出)运算规律
&与运算true & true = true
true & false = false
false & true = false
false & false = false
1. 任意一边为 false → 结果为 false
2. 两边均为 true → 结果为 true
|或运算true | true = true
true | false = true
false | true = true
false | false = false
1. 任意一边为 true → 结果为 true
2. 两边均为 false → 结果为 false
^异或true ^ true = false
true ^ false = true
false ^ true = true
false ^ false = false
1. 两边相同 → 结果为 false
2. 两边不同 → 结果为 true
!非运算!true = false
!false = true
单目运算,取反布尔值

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/14 19:50* @Version: v1.0.0* @Description: TODO**/
public class LogicalOperators {public static void main(String[] args) {// 1. 与运算(&)示例System.out.println("=== 与运算(&) ===");System.out.println("true & true = " + (true & true));     // trueSystem.out.println("true & false = " + (true & false));   // falseSystem.out.println("false & true = " + (false & true));   // falseSystem.out.println("false & false = " + (false & false)); // false// 2. 或运算(|)示例System.out.println("\n=== 或运算(|) ===");System.out.println("true | true = " + (true | true));     // trueSystem.out.println("true | false = " + (true | false));   // trueSystem.out.println("false | true = " + (false | true));   // trueSystem.out.println("false | false = " + (false | false)); // false// 3. 异或运算(^)示例System.out.println("\n=== 异或运算(^) ===");System.out.println("true ^ true = " + (true ^ true));     // falseSystem.out.println("true ^ false = " + (true ^ false));   // trueSystem.out.println("false ^ true = " + (false ^ true));   // trueSystem.out.println("false ^ false = " + (false ^ false)); // false// 4. 非运算(!)示例System.out.println("\n=== 非运算(!) ===");System.out.println("!true = " + (!true));   // falseSystem.out.println("!false = " + (!false)); // true}
}

在这里插入图片描述

5.5.2 短路与、短路或

&&和&的运算结果相同,但运算过程存在差异:

  1. &:无论左侧运算结果如何,右侧都会参与运算
  2. &&:
    a. 如果左边运算结果为false,那么右边就不需要参与运算,直接返回结果false。
    b. 如果左边运算结果为true,那么继续执行右边的运算,并返回右边运算的结果。

||和|的运算结果相同,但运算过程存在差异:

  1. |:无论左侧运算结果如何,右侧都会参与运算
  2. ||:
    a. 如果左边运算结果为true,那么右边就不需要参与运算,直接返回结果true。
    b. 如果左边运算结果为false,那么继续执行右边的运算,并返回右边运算的结果
运算符名称运算特点
&&短路与只要有一个为false,结果就为false
||短路或只要有一个为true,结果就为true

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/14 20:09* @Version: v1.0.0* @Description: TODO**/
import java.util.Optional;public class ShortCircuitOperators {public static void main(String[] args) {int x = 10;int y = 20;// ===== 短路与(&&)示例 =====System.out.println("===== 短路与(&&)示例 =====");// 示例1: 左侧为false,右侧不执行System.out.println("\n示例1: 左侧为false,右侧不执行");x = 10;boolean result1 = (x > 15) && (++x > 0);System.out.println("结果: " + result1); // falseSystem.out.println("x的值: " + x);      // 10 (x没有增加,说明右侧没有执行)// 示例2: 左侧为true,右侧执行System.out.println("\n示例2: 左侧为true,右侧执行");x = 10;boolean result2 = (x > 5) && (++x > 0);System.out.println("结果: " + result2); // trueSystem.out.println("x的值: " + x);      // 11 (x增加了,说明右侧执行了)// 示例3: 与普通与运算符(&)的对比System.out.println("\n示例3: 与普通与运算符(&)的对比");x = 10;boolean result3 = (x > 15) & (++x > 0);System.out.println("结果: " + result3); // falseSystem.out.println("x的值: " + x);      // 11 (x增加了,说明右侧执行了)// ===== 短路或(||)示例 =====System.out.println("\n===== 短路或(||)示例 =====");// 示例1: 左侧为true,右侧不执行System.out.println("\n示例1: 左侧为true,右侧不执行");y = 20;boolean result4 = (y > 15) || (++y > 0);System.out.println("结果: " + result4); // trueSystem.out.println("y的值: " + y);      // 20 (y没有增加,说明右侧没有执行)// 示例2: 左侧为false,右侧执行System.out.println("\n示例2: 左侧为false,右侧执行");y = 20;boolean result5 = (y < 15) || (++y > 0);System.out.println("结果: " + result5); // trueSystem.out.println("y的值: " + y);      // 21 (y增加了,说明右侧执行了)// 示例3: 与普通或运算符(|)的对比System.out.println("\n示例3: 与普通或运算符(|)的对比");y = 20;boolean result6 = (y > 15) | (++y > 0);System.out.println("结果: " + result6); // trueSystem.out.println("y的值: " + y);      // 21 (y增加了,说明右侧执行了)}
}

在这里插入图片描述

【随堂练习】

  1. 判断一个数是否在4(包含)~6(不包含)之间;
  2. 判断一个数是否在4(不包含)~6(包含)之外;

5.6 位运算符(了解一下)

位运算是直接对二进制进行的运算。

5.6.1 <<左移

左移n位,等于在原数据上乘以2的n次方。
例如:3 << 1 = 6

  • 00000000 00000000 00000000 00000011
  • 0 0000000 00000000 00000000 000000110 左移低位补0

例如:3 << 2 = 12

  • 00000000 00000000 00000000 00000011
  • 00 000000 00000000 00000000 0000001100

【使用技巧】 3*2可以使用 3<<1来实现,这样做的效率更高。

5.6.2 >>右移

右移n位,等于在源数据上除以2的n次方
例如:6 >> 1 = 3

  • 0000 0000 0000 0000 0000 0000 0000 0110
  • 00000 0000 0000 0000 0000 0000 0000 011 0 正数则在高位补0,负数则在高位补1

例如:6 >> 2 = 1

  • 0000 0000 0000 0000 0000 0000 0000 0110
  • 000000 0000 0000 0000 0000 0000 0000 01 10

【使用技巧】 3/2可以使用 3>>1来实现,这样做的效率更高。

5.6.3 >>>无符号右移

>>> 和 >> 操作符类似,但无论值的正负,>>> 都会在高位补 0。

5.6.4 &位运算

位都为1,结果才为1,否则结果为0

例如:12 & 5 = 4

计算过程:
1100 (12)
& 0101 (5)
-------
0100 (4)

从右到左逐位进行与运算:
第1位:0 & 1 = 0
第2位:0 & 0 = 0
第3位:1 & 1 = 1
第4位:1 & 0 = 0

5.6.5 |位运算

位只要有一个为1,那么结果就是1,否则就为0

例如:10 | 6 = 14

计算过程:
1010 (10)
| 0110 (6)
--------
1110 (14)

从右到左逐位进行或运算:
第1位:0 | 0 = 0
第2位:1 | 1 = 1
第3位:0 | 1 = 1
第4位:1 | 0 = 1

5.6.6 ^位运算

两个操作数的位中,相同则结果为0,不同则结果为1
例如:9 ^ 5 = 12
计算过程:
1001 (9)
^ 0101 (5)
----
1100 (12)

5.6.7 ~位运算

如果位为0,结果是1,如果位为1,结果是0
例如:~12 = -13
计算过程:
原始数字 12:
0000 0000 0000 0000 0000 0000 0000 1100

取反后:
1111 1111 1111 1111 1111 1111 1111 0011 (-13)

为什么是-13?
1. 在计算机中,负数以补码形式存储
2. 最高位1表示负数
3. 要得到这个负数的值,需要:
- 取反: 0000 0000 0000 0000 0000 0000 0000 1100
- 加1: +1
得到: 0000 0000 0000 0000 0000 0000 0000 1101 (13)
因此结果是-13

5.7 三目运算符

三目运算符又称为三元运算。
语法格式:条件表达式? 表达式1 : 表达式2
如果条件表达式为true,则取表达式1的值,否则就取表达式2的值。

【示例】

/*** @Author: chenxiezhu* @Date: 2025/5/14 21:08* @Version: v1.0.0* @Description: TODO**/
public class TernaryOperatorExample {public static void main(String[] args) {// 示例1:基础用法 - 判断大小int a = 10;int b = 20;int max = a > b ? a : b;System.out.println("较大的数是:" + max);  // 输出:20// 示例2:判断奇偶int number = 7;String result = number % 2 == 0 ? "偶数" : "奇数";System.out.println(number + " 是" + result);  // 输出:7 是奇数// 示例3:嵌套使用(虽然可以,但不推荐,会降低代码可读性)int score = 85;String grade =  score >= 90 ? "优秀" :score >= 80 ? "良好" :score >= 60 ? "及格" : "不及格";System.out.println("成绩等级:" + grade);  // 输出:良好// 示例4:结合字符串boolean isVIP = true;double price = 100.0;double finalPrice = isVIP ? price * 0.8 : price;System.out.println("最终价格:" + finalPrice);  // 输出:80.0}
}

在这里插入图片描述

【随堂练习】

  1. 获取两个数的最大值或最小值

5.8 运算符优先级

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

备注:这些不需要去刻意的记这些优先级,在表达式中建议优先使用小括号来明确运算顺序。

相关文章:

  • git push 报错:send-pack: unexpected disconnect while reading sideband packet
  • c#队列及其操作
  • vscode调试c/c++
  • 在linux中,如何使用malloc()函数向操作系统申请堆内存,使用free()函数释放内存。
  • python打包exe报错:处理文件时错误:Excel xlsx file; not supported
  • Python常见问题
  • 深入理解 Dijkstra 算法:原理、实现与优化
  • openfeign与dubbo调用下载excel实践
  • 如何获得sqoop-1.4.6.2.3.99.0-195.jar
  • 保持视频二维码不变,更新视频的内容
  • GMT之Bash语言使用
  • 濒危仙草的重生叙事:九仙尊米斛花节如何以雅集重构中医药文化IP
  • Qt原型模式实现与应用
  • (4)python开发经验
  • BRPickerView
  • ansible进阶02
  • 鸿蒙OSUniApp 制作动态加载的瀑布流布局#三方框架 #Uniapp
  • 【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
  • C++引用编程练习
  • 文件名是 ‪E:\20250512_191204.mp4, EV软件录屏,未保存直接关机损坏, 如何修复?
  • 时隔3年俄乌直接谈判今日有望重启:谁参加,谈什么
  • 腾讯一季度营收增长13%,马化腾:战略性的AI投入将带来长期回报
  • 广东省原省长卢瑞华逝世,享年88岁
  • Manus向全球用户开放注册
  • 迪奥部分客户数据遭泄露,公司称正持续展开调查
  • 上海现有超12.3万名注册护士,本科及以上学历占一半