Java基础06:变量、常量、作用域 学习笔记
一、变量
1. 定义
变量是程序运行过程中值可以发生改变的量,是用来存储数据的内存空间标识,通过变量名可以访问和操作对应的内存区域。
2. 变量的三要素
- 数据类型:限定变量能存储的数据种类(如 int、String、double 等),决定内存空间大小。
- 变量名:符合 Java 命名规范的标识符,用于标识变量。
- 值:变量存储的具体数据,需与数据类型匹配。
3. 变量的声明与赋值
声明格式
数据类型 变量名;
赋值格式
变量名 = 数值;
声明并赋值(常用)
数据类型 变量名 = 数值;
代码示例
// 先声明后赋值
int age;
age = 20;
// 声明并赋值
String name = "Java";
double score = 95.5;
4. Java 命名规范(变量 / 方法)
- 由字母、数字、下划线
_、美元符$组成,不能以数字开头。 - 严格区分大小写,如
age和Age是两个不同变量。 - 不能使用 Java 关键字(如 int、class、if 等)。
- 采用驼峰命名法:首字母小写,后续单词首字母大写,如
studentName、getScore。 - 命名要做到见名知意,避免使用 a、b、c 等无意义字符。
5. 变量的使用注意
- 变量必须先声明,后赋值,再使用,未赋值直接使用会编译报错。
- 同一作用域内,不能定义重名变量。
- 变量的取值范围受数据类型和作用域限制。
二、常量
1. 定义
常量是程序运行过程中值始终固定不变的量,一旦赋值后,无法再修改其值。
2. 声明关键字
使用final关键字修饰,final 为 Java 的修饰符,代表 “最终的”。
3. 声明格式
final 数据类型 常量名 = 数值;
代码示例
// 声明整型常量
final int MAX_SCORE = 100;
// 声明浮点型常量
final double PI = 3.1415926;
// 声明字符串常量
final String SCHOOL_NAME = "狂神说Java";
4. 常量的命名规范
- 遵循变量命名的基础规则(不能以数字开头、不使用关键字等)。
- 采用全大写命名,多个单词之间用下划线_分隔,如
MAX_AGE、DEFAULT_PASSWORD,便于一眼区分变量和常量。
5. 常量的使用注意
- 常量必须在声明时直接赋值,不能先声明后赋值,否则编译报错。
- 赋值后不可修改,若尝试重新赋值,编译器会直接报错。
- 常量可用于表示程序中固定的配置值(如最大值、固定参数、系统常量等),提高代码的可读性和维护性。
三、作用域
1. 定义
作用域指变量 / 常量在程序中能被访问的有效范围,超出该范围后,变量 / 常量会被 Java 虚拟机(JVM)回收,无法再使用。
2. 常见的作用域分类
根据定义位置,Java 中主要分为局部作用域和成员作用域(本章节基础阶段核心讲解局部与类成员)。
(1)局部变量
-
定义位置:声明在方法体、代码块(如 if、for、while 块)、方法参数中的变量。
-
作用范围:仅在其定义的方法体 / 代码块内有效,出了该范围立即失效。
-
使用注意:
- 局部变量必须显式赋值后才能使用,JVM 不会为其分配默认值。
- 局部变量不能使用访问修饰符(如 public、private、protected)。
- 代码块内的局部变量,外部无法访问。
(2)成员变量(实例变量)
-
定义位置:声明在类中,方法体之外的变量,属于类的实例(对象)。
-
作用范围:整个类中都可访问,随对象的创建而存在,随对象的销毁而回收。
-
使用注意:
- JVM 会为成员变量分配默认值,无需显式赋值即可使用(整数 0、浮点 0.0、布尔 false、引用类型 null)。
- 可使用访问修饰符修饰,控制其访问权限。
3. 作用域的核心规则
- 就近原则:如果局部作用域中定义了与成员作用域同名的变量,在局部范围内,优先访问局部变量。
- 重名限制:同一作用域内不能重名,不同作用域内可以定义同名变量,相互独立互不影响。
4. 代码示例(作用域演示)
public class VariableScope {
// 成员变量,作用域:整个类
String name = "全局变量";
int age = 18;
public void test() {
// 局部变量,作用域:test方法内
String name = "局部变量";
// 就近原则:访问局部变量的name
System.out.println(name); // 输出:局部变量
// 访问成员变量的age
System.out.println(age); // 输出:18
if (true) {
// 代码块内的局部变量,作用域:仅if块内
int score = 90;
System.out.println(score); // 输出:90
}
// 报错:score超出作用域,无法访问
// System.out.println(score);
}
}
四、变量与常量的核心对比
| 对比维度 | 变量 | 常量 |
|---|---|---|
| 修饰关键字 | 无(可加访问修饰符) | 必须加 final |
| 值的可变性 | 运行中可修改 | 一旦赋值,不可修改 |
| 赋值时机 | 可先声明后赋值,也可声明即赋值 | 必须声明时直接赋值 |
| 命名规范 | 小驼峰命名法,见名知意 | 全大写,下划线分隔 |
| 内存特性 | 随作用域结束回收,值动态变化 | 随类 / 对象存在,值始终固定 |
| 适用场景 | 存储程序运行中需要动态修改的数据 | 存储程序中固定不变的配置值 / 常量 |
五、基础阶段核心注意点
- 局部变量是 Java 基础阶段最常用的变量,重点掌握声明 - 赋值 - 使用的流程,牢记 “先赋值再使用”。
- final 修饰的常量,不仅可以修饰基本数据类型,也可修饰引用数据类型(基础阶段暂不深入),核心特性均为 “值不可变”。
- 作用域的边界是大括号 {} ,一对 {} 代表一个独立的局部作用域,内部定义的变量外部无法访问。
- 变量的命名规范是 Java 编码的基础,从入门开始严格遵守,养成良好的编码习惯。
- 成员变量的默认值是基础考点,需熟记:int→0、double→0.0、boolean→false、String→null。
Java基础07:运算符 学习笔记
一、运算符概述
- 运算符是用于对常量和变量进行运算操作的符号,通过运算符可以实现数据的计算、比较、赋值等操作。
- Java 运算符按功能可分为算术运算符、赋值运算符、比较运算符、逻辑运算符、自增自减运算符等,是 Java 基础编程的核心基础。
- 运算符操作的数称为操作数,单个操作数的为单目运算符,两个为双目运算符,三个为三目运算符(三元运算符)。
二、算术运算符
1. 基本算术运算符
| 运算符 | 作用 | 示例 | 结果 |
|---|---|---|---|
+ | 加法 / 字符串拼接 | 10+20/"Java"+"学习" | 30/Java学习 |
- | 减法 / 取负 | 20-10/-10 | 10/-10 |
* | 乘法 | 10*20 | 200 |
/ | 除法 | 20/10/20/3 | 2/6(整数相除取整) |
% | 取模(求余数) | 20%3/10%2 | 2/0 |
2. 关键注意点
- 整数相除时,结果只保留整数部分,舍弃小数部分(无四舍五入);若需保留小数,需将其中一个操作数转为浮点型(如
20.0/3)。 - 取模运算的结果符号与被除数一致,如
-20%3=-2、20%-3=2。 +作为字符串拼接符时,只要其中一个操作数是字符串,其他操作数会自动转为字符串进行拼接,如10+"20"结果为"1020"。
3. 代码示例
// 基本运算
int a = 20, b = 3;
System.out.println(a + b); // 23
System.out.println(a / b); // 6
System.out.println(a % b); // 2
// 浮点型除法
System.out.println((double)a / b); // 6.666666666666667
// 字符串拼接
System.out.println("数字:" + a); // 数字:20
System.out.println(a + b + "结果"); // 23结果
System.out.println("结果" + a + b); // 结果203
三、自增自减运算符(++ /--)
1. 作用
对变量的值进行加 1或减 1操作,属于单目运算符,仅能操作变量,不能操作常量(如10++编译报错)。
2. 两种使用方式
| 方式 | 语法 | 执行规则 | 示例 | 结果 |
|---|---|---|---|---|
| 前置 | ++变量/--变量 | 先运算,后使用 | int a=10; int b=++a; | a=11,b=11 |
| 后置 | 变量++/变量-- | 先使用,后运算 | int a=10; int b=a++; | a=11,b=10 |
3. 代码示例
int a = 10;
// 前置自增
int b = ++a;
System.out.println(a); // 11
System.out.println(b); // 11
// 后置自增
int c = 10;
int d = c++;
System.out.println(c); // 11
System.out.println(d); // 10
// 自减同理
int e = 10;
int f = --e;
System.out.println(e); //9
System.out.println(f); //9
四、赋值运算符
1. 基本赋值运算符
=:将右侧的值赋给左侧的变量,如int a=10;(注意:=是赋值,不是等于,等于用==表示)。
2. 复合赋值运算符
由基本赋值运算符与算术运算符结合而成,会自动进行类型转换(适合 byte/short 等小范围类型)。
| 运算符 | 作用 | 等价于 | 示例 | 结果 |
|---|---|---|---|---|
+= | 加后赋值 | a = a + b | int a=10; a+=20; | 30 |
-= | 减后赋值 | a = a - b | int a=20; a-=10; | 10 |
*= | 乘后赋值 | a = a * b | int a=10; a*=2; | 20 |
/= | 除后赋值 | a = a / b | int a=20; a/=2; | 10 |
%= | 取模后赋值 | a = a % b | int a=20; a%=3; | 2 |
3. 代码示例
int a = 10;
a += 5; // 等价于a = a +5
System.out.println(a); //15
byte b = 5;
// 复合赋值自动类型转换,无需手动强转
b += 3; // 等价于b = (byte)(b+3)
System.out.println(b); //8
// 普通赋值需强转,否则报错
// b = b +3; 编译报错:int转byte可能丢失精度
五、比较运算符(关系运算符)
1. 作用
用于比较两个操作数的大小或相等关系,结果永远是 boolean 类型(true/false) ,常用于 if、for 等条件判断。
2. 常用比较运算符
| 运算符 | 作用 | 示例 | 结果 |
|---|---|---|---|
== | 等于 | 10==20/"Java"=="Java" | false/true |
!= | 不等于 | 10!=20 | true |
> | 大于 | 20>10 | true |
< | 小于 | 20<10 | false |
>= | 大于等于 | 10>=10 | true |
<= | 小于等于 | 10<=20 | true |
3. 关键注意点
- 比较基本数据类型时,
==比较的是值;比较引用数据类型时(如 String),==比较的是地址值(基础阶段暂不深入)。 - 切勿将
==写成=,否则会变成赋值操作,导致条件判断逻辑错误(如if(a=10)永远为 true)。
4. 代码示例
int a = 10, b = 20;
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a > b); // false
boolean flag = (a <= b);
System.out.println(flag); // true
六、逻辑运算符
1. 作用
用于连接多个 boolean 类型的表达式,结果仍为 boolean 类型,常用于多条件判断。
2. 常用逻辑运算符(双目)
| 运算符 | 名称 | 运算规则 | 示例 | 结果 | ||||
|---|---|---|---|---|---|---|---|---|
&& | 短路与 | 两边都为 true,结果才为 true; 左边为 false,右边不执行 | 10>20 && 10>5 | false | ||||
& | 逻辑与 | 两边都为 true,结果才为 true; 左边为 false,右边仍执行 | 10>20 & 10>5 | false | ||||
| ` | ` | 短路或 | 两边有一个为 true,结果就为 true; 左边为 true,右边不执行 | `10>5 | 10>20` | true | ||
| ` | ` | 逻辑或 | 两边有一个为 true,结果就为 true; 左边为 true,右边仍执行 | `10>5 | 10>20` | true | ||
! | 逻辑非(单目) | 取反,true 变 false,false 变 true | !(10>5) | false |
3. 核心重点:短路特性
&&和||的短路特性能提高程序运行效率,避免无效代码执行,开发中优先使用。
4. 代码示例
int a = 10;
// 短路与:左边false,右边a++不执行
boolean b1 = (a > 20) && (a++ > 5);
System.out.println(b1); // false
System.out.println(a); // 10
// 逻辑与:左边false,右边a++仍执行
boolean b2 = (a > 20) & (a++ > 5);
System.out.println(b2); // false
System.out.println(a); // 11
// 短路或:左边true,右边a++不执行
boolean b3 = (a > 5) || (a++ > 20);
System.out.println(b3); // true
System.out.println(a); // 11
七、三元运算符(三目运算符)
1. 语法格式
条件表达式 ? 表达式1 : 表达式2;
2. 运算规则
-
先判断条件表达式的结果:
- 若为
true,执行表达式 1,并将其结果作为整个三元运算的结果; - 若为
false,执行表达式 2,并将其结果作为整个三元运算的结果。
- 若为
-
表达式 1 和表达式 2 的数据类型必须一致(或可自动类型转换)。
3. 代码示例
// 求两个数的最大值
int a = 10, b = 20;
int max = a > b ? a : b;
System.out.println(max); // 20
// 求三个数的最大值(嵌套使用)
int c = 15;
int max3 = (a > b ? a : b) > c ? (a > b ? a : b) : c;
System.out.println(max3); //20
// 结果赋值给字符串
String res = a > b ? "a更大" : "b更大";
System.out.println(res); // b更大
八、运算符的优先级
- Java 中运算符的优先级决定了表达式的执行顺序,优先级高的先执行,优先级低的后执行。
- 核心优先级排序(从高到低): 括号 () > 自增自减 (++/--) > 算术运算符 (* / % > + -) > 比较运算符 > 逻辑运算符 (&& > ||) > 三元运算符 > 赋值运算符
- 开发中无需死记优先级,通过小括号 () 明确执行顺序,代码更易读(推荐做法)。
代码示例
// 优先级默认执行
int res1 = 10 + 20 * 3;
System.out.println(res1); //70(先乘后加)
// 括号改变执行顺序
int res2 = (10 + 20) * 3;
System.out.println(res2); //90(先加后乘)
九、基础阶段核心注意点
- 整数除法的取整特性和取模的符号规则是高频考点,需重点掌握。
- 自增自减的前置 / 后置区别是基础易错点,记住前置先算后用,后置先用后算。
- 复合赋值运算符会自动类型转换,适合小范围数据类型(byte/short),普通赋值需手动强转。
- 开发中优先使用
&&和||,利用短路特性提升程序效率,避免&和|的无效执行。 - 三元运算符可简化简单的 if-else 判断,嵌套使用时需注意可读性,复杂判断建议用 if-else。
- 避免因运算符优先级导致的逻辑错误,优先用小括号明确执行顺序。
Java基础补充:位运算符 学习笔记
位运算符是 Java 中直接对二进制位(bit) 进行操作的运算符,运算速度极快(底层直接操作内存),常用于底层开发、性能优化、加密算法等场景。
一、位运算符核心前提
- 操作对象:仅支持整数类型(byte、short、int、long),不能操作浮点数、布尔值等其他类型。
- 运算本质:将十进制数转换为补码(正数补码 = 原码,负数补码 = 反码 + 1)后,按位逐位计算,结果再转回十进制。
- 位的表示:以
int类型为例,占 32 位,最高位是符号位(0 = 正数,1 = 负数)。
二、7 个位运算符分类与详解
1. 按位与(&)
-
规则:两个对应位都为 1,结果才为 1,否则为 0(遇 0 则 0)。
-
特性:清零(可将指定位设为 0)、判断奇偶(最后一位为 1 则奇数,0 则偶数)。
-
代码示例
-
// 4 = 0000 0100,5 = 0000 0101 int a = 4 & 5; // 结果:0000 0100 → 4 // 判断奇偶 System.out.println(3 & 1); // 1(奇数) System.out.println(4 & 1); // 0(偶数)
-
2. 按位或(|)
-
规则:两个对应位有一个为 1,结果就为 1,否则为 0(遇 1 则 1)。
-
特性:置位(可将指定位设为 1)。
-
代码示例
-
// 4 = 0000 0100,5 = 0000 0101 int b = 4 | 5; // 结果:0000 0101 → 5
-
3. 按位异或(^)
-
规则:两个对应位相同为 0,不同为 1(同 0 异 1)。
-
核心特性:
- 一个数异或自身等于 0:
a ^ a = 0 - 一个数异或 0 等于自身:
a ^ 0 = a - 可交换、可结合(开发中常用于交换变量、简单加密)。
- 一个数异或自身等于 0:
-
代码示例
-
// 交换两个数(无需临时变量,经典技巧) int x = 10, y = 20; x = x ^ y; // x = 10^20 y = x ^ y; // y = (10^20)^20 = 10 x = x ^ y; // x = (10^20)^10 = 20 System.out.println(x); // 20 System.out.println(y); // 10 // 4 = 0000 0100,5 = 0000 0101 int c = 4 ^ 5; // 结果:0000 0001 → 1
-
4. 按位取反(~)
-
规则:单目运算符,逐位取反(0 变 1,1 变 0),包括符号位。
-
核心特性:
~a = -a - 1(补码运算规律)。 -
代码示例
-
// 3 = 0000 0011 int d = ~3; // 补码取反:1111 1100(补码)→ 原码:1000 0100 → 十进制:-4 System.out.println(d); // -4
-
5. 左移(<<)
-
规则:将二进制位整体左移 n 位,低位补 0,高位溢出丢弃。
-
等价关系:左移 n 位 = 乘以 2 的 n 次方(
a << n ≈ a * 2^n),比乘法运算快得多。 -
注意:左移可能导致溢出,结果超出 int 范围则变为负数。
-
代码示例
-
// 4 = 0000 0100 int e = 4 << 2; // 左移2位:0001 0000 → 16(等价4*4) System.out.println(e); // 16
-
6. 右移(>>)
-
规则:将二进制位整体右移 n 位,符号位不变(正数高位补 0,负数高位补 1)。
-
等价关系:右移 n 位 = 除以 2 的 n 次方(
a >> n ≈ a / 2^n),向下取整。 -
代码示例
-
// 16 = 0001 0000 int f = 16 >> 2; // 右移2位:0000 0100 → 4(等价16/4) System.out.println(f); // 4 // 负数右移(符号位补1) int g = -4 >> 2; // 结果:-1 System.out.println(g); // -1
-
7. 无符号右移(>>>)
-
规则:将二进制位整体右移 n 位,无论正负,高位统一补 0(Java 独有)。
-
注意:仅对正数运算结果与
>>一致,负数运算结果为正数(符号位被 0 覆盖)。 -
代码示例
-
// -4 = 1111 1111 1111 1111 1111 1111 1111 1100 int h = -4 >>> 2; // 右移2位高位补0:0011 1111 1111 1111 1111 1111 1111 1111 System.out.println(h); // 1073741823
-
三、位运算符核心对比表
| 运算符 | 名称 | 核心规则 | 典型应用场景 | 等价运算(正数) | |
|---|---|---|---|---|---|
| & | 按位与 | 遇 0 则 0,两 1 才 1 | 清零、判断奇偶 | - | |
| 按位或 | 遇 1 则 1,两 0 才 0 | 置位、权限控制 | - | ||
| 按位异或 | 同 0 异 1 | 变量交换、简单加密 | - | ||
| ~ | 按位取反 | 0 变 1,1 变 0 | 补码运算、位掩码 | - | |
| << | 左移 | 低位补 0,高位溢出 | 快速乘法、底层移位 | * 2^n | |
| >> | 右移 | 符号位不变,低位丢弃 | 快速除法、取整 | / 2^n(向下取整) | |
| >>> | 无符号右移 | 高位统一补 0 | 无符号数处理、二进制解析 | - |
四、开发中高频使用技巧
- 快速计算 2 的幂次:用
1 << n代替Math.pow(2, n),速度更快(如1 << 10 = 1024)。 - 高效取余:对 2 的幂次取余(如
a % 8),可用a & 7替代(仅适用于正数)。 - 交换变量:利用异或特性,无需临时变量(但可读性稍差,实际开发慎用)。
- 权限控制:用不同位表示不同权限(如第 0 位 = 查看,第 1 位 = 新增),通过位运算快速判断 / 设置权限。
五、核心注意点
- 位运算优先级:低于算术运算符,建议用括号明确优先级(如
(a & b) + c)。 - 负数运算:必须先理解补码规则,否则易得出错误结果(尤其是右移和无符号右移)。
- 溢出问题:左移易导致数值溢出,需提前判断取值范围。
- 实际场景:日常业务开发中用得较少,主要集中在底层框架、性能优化、算法、硬件交互等领域。
Java基础09:流程控制
一、流程控制概述
Java 流程控制用于规范程序的执行顺序,核心分为顺序结构、选择结构、循环结构,而Scanner 类是实现程序与用户交互的核心工具,能获取键盘输入的各类数据,是流程控制中实现动态逻辑的基础,也是 P31 的核心讲解内容。
二、Scanner 类核心知识点
1. 类的作用
java.util.Scanner是 Java5 新增的 IO 工具类,专门用于获取用户键盘输入,支持字符串、整数、浮点型等多种数据类型的输入获取,是基础阶段实现用户交互的唯一方式。
2. 使用前置条件
必须先导入 Scanner 包,且导包语句需写在程序最上方,语法:
import java.util.Scanner; // 导入Scanner包,固定写法
3. 核心使用步骤(四步走)
- 创建 Scanner 对象:关联系统输入流,建立程序与键盘的连接;
- 判断输入(可选) :通过
hasNextXxx()判断用户是否输入指定类型数据,避免程序报错; - 获取输入:通过
nextXxx()获取用户输入的具体数据; - 关闭 Scanner:释放系统资源,避免内存泄漏,使用后必须关闭。
4. 核心方法分类
(1)判断输入的方法(hasNextXxx())
hasNext():判断是否有有效字符串输入(非空白);hasNextLine():判断是否有一行内容输入(可含空白);hasNextInt()/hasNextDouble():判断是否有整数 / 浮点型数据输入。
(2)获取输入的方法(nextXxx())
| 方法 | 取值规则 | 能否接收空格 | 结束符 |
|---|---|---|---|
next() | 从有效字符开始取值 | 否 | 空白(空格 / 制表符) |
nextLine() | 从光标开始取整行内容 | 是 | 回车(Enter) |
nextInt() | 仅获取整数类型数据 | 否 | 空白 / 回车 |
nextDouble() | 仅获取浮点型数据 | 否 | 空白 / 回车 |
5. 完整代码示例(基础字符串输入)
// 1. 导包(程序最上方,仅需写一次)
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
// 2. 创建Scanner对象,固定写法
Scanner sc = new Scanner(System.in);
System.out.println("请输入内容:");
// 3. 判断并获取输入
if (sc.hasNextLine()) { // 判断是否有行输入
String str = sc.nextLine(); // 获取输入的字符串
System.out.println("你输入的内容是:" + str);
}
// 4. 关闭Scanner,释放资源
sc.close();
}
}
6. 两种核心字符串获取方法对比
next() 示例
Scanner sc = new Scanner(System.in);
System.out.println("请输入内容(next()):");
if (sc.hasNext()) {
String s = sc.next(); // 输入:Hello World → 仅获取Hello
System.out.println(s); // 输出:Hello
}
sc.close();
nextLine() 示例
Scanner sc = new Scanner(System.in);
System.out.println("请输入内容(nextLine()):");
if (sc.hasNextLine()) {
String s = sc.nextLine(); // 输入:Hello World → 获取整行
System.out.println(s); // 输出:Hello World
}
sc.close();
开发建议:优先使用nextLine(),支持任意内容输入,适配绝大多数场景。
7. 数值类型输入示例(整数 / 浮点型)
import java.util.Scanner;
public class ScannerNum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 整数输入
System.out.println("请输入整数:");
if (sc.hasNextInt()) {
int num = sc.nextInt();
System.out.println("你输入的整数:" + num);
}
// 浮点型输入
System.out.println("请输入小数:");
if (sc.hasNextDouble()) {
double d = sc.nextDouble();
System.out.println("你输入的小数:" + d);
}
sc.close();
}
}
三、Scanner 使用核心注意点
- 导包位置:
import java.util.Scanner必须写在类定义之前,程序最上方,否则编译报错。 - 对象创建:
Scanner sc = new Scanner(System.in)为固定写法,System.in表示关联系统输入流。 - 方法匹配:
hasNextXxx()与nextXxx()必须类型匹配,如hasNextInt()对应nextInt()。 - 资源关闭:使用完毕后必须执行
sc.close(),Scanner 属于 IO 流,不关闭会占用系统资源。 - 空白处理:
next()会自动忽略输入前的空白,且遇到空白立即停止取值,无法接收带空格的字符串。 - 换行符问题:若在
nextInt()/next()后直接使用nextLine(),需额外处理换行符(sc.nextLine()),否则会直接读取空行。
四、Scanner 与流程控制的结合
Scanner 的核心价值是为流程控制提供动态数据,让程序能根据用户输入执行不同逻辑,示例:
import java.util.Scanner;
public class ScannerIf {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的成绩:");
if (sc.hasNextInt()) {
int score = sc.nextInt();
// 结合选择结构(if)实现动态判断
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
} else {
System.out.println("请输入有效的整数成绩!");
}
sc.close();
}
}
五、IDEA 快捷操作
在 IDEA 中,创建 Scanner 对象可使用快捷键快速生成:
- 输入
sc,按Tab键,快速生成Scanner sc = new Scanner(System.in);; - 输入
sc.close,按Tab键,快速生成sc.close();。
六、拓展:多组数据输入
通过循环结构可实现 Scanner 的多组数据输入,示例(输入多个整数,以非整数结束):
import java.util.Scanner;
public class ScannerFor {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入多个整数,输入非整数结束:");
while (sc.hasNextInt()) { // 循环判断,直到输入非整数
int num = sc.nextInt();
System.out.println("你输入的整数:" + num);
}
System.out.println("输入结束!");
sc.close();
}
}
Java基础10:流程控制(顺序结构与选择结构if)
一、流程控制三大核心结构
Java 程序的执行顺序由流程控制结构决定,核心分为三类,顺序结构是基础,选择结构和循环结构是实现程序逻辑分支、重复执行的核心,本章节重点讲解顺序结构和选择结构之 if 语句。
- 顺序结构:程序默认的执行结构,从上到下、从左到右依次执行每一行代码,无跳转、无分支。
- 选择结构:根据条件判断结果,选择执行不同的代码块,核心为
if语句和switch语句(P32 重点讲 if)。 - 循环结构:根据循环条件,重复执行某一段代码,核心为
for、while、do-while语句。
二、顺序结构
1. 核心特点
- 是 Java 中最简单、最基础的流程控制结构,所有程序都包含顺序结构。
- 代码执行无任何判断和跳转,严格按照书写顺序执行,一行执行完毕后自动执行下一行。
- 顺序结构中,任何一条语句都不会被跳过或重复执行。
2. 代码示例
// 纯顺序结构执行:从上到下依次执行
public class SequenceDemo {
public static void main(String[] args) {
System.out.println("第一步:执行代码1");
int a = 10 + 20;
System.out.println("第二步:计算结果a=" + a);
String str = "Java流程控制";
System.out.println("第三步:定义字符串" + str);
}
}
// 执行结果:按代码书写顺序依次输出三行内容
3. 注意点
顺序结构是所有复杂结构的基础,选择结构、循环结构中,代码块内部的执行逻辑仍遵循顺序结构。
三、选择结构之 if 语句
if 语句是 Java 中最常用的选择结构,通过boolean 类型的条件表达式判断结果(true/false),决定是否执行对应的代码块,分为单分支、双分支、多分支三种形式,可嵌套使用。
1. 单分支 if 语句(基础版)
适用场景
仅当条件满足时执行某段代码,条件不满足则跳过该代码块,继续执行后续代码。
语法格式
if (条件表达式) {
// 条件为true时,执行的代码块
}
// 条件为false时,直接执行此处后续代码
核心规则
- 条件表达式必须是 boolean 类型(true/false),不能是数值、字符串等其他类型。
- 若代码块内只有一行代码,大括号
{}可省略(开发中不推荐,易出逻辑错误)。 - 条件表达式可使用比较运算符、逻辑运算符组合实现复杂判断。
代码示例(结合 Scanner)
import java.util.Scanner;
public class IfSingleDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的年龄:");
int age = sc.nextInt();
// 单分支if:年龄满18岁则执行代码块
if (age >= 18) {
System.out.println("你已成年,可独立操作!");
}
System.out.println("程序执行完毕");
sc.close();
}
}
2. 双分支 if-else 语句
适用场景
条件满足时执行 A 代码块,条件不满足时执行 B 代码块,二选一执行,无第三种情况。
语法格式
if (条件表达式) {
// 条件为true时,执行的代码块1
} else {
// 条件为false时,执行的代码块2
}
核心规则
- if 和 else 的代码块永远只会执行其中一个,不会同时执行,也不会都不执行。
- else 后无任何条件表达式,直接匹配 if 的相反条件。
代码示例(结合 Scanner)
import java.util.Scanner;
public class IfElseDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的考试分数:");
int score = sc.nextInt();
// 双分支if-else:分数及格/不及格二选一
if (score >= 60) {
System.out.println("恭喜你,考试及格!");
} else {
System.out.println("很遗憾,考试不及格,继续努力!");
}
sc.close();
}
}
3. 多分支 if-else if-else 语句
适用场景
存在多个条件判断,按顺序依次判断,满足某个条件则执行对应代码块,后续条件不再判断,最终可加 else 匹配所有不满足的情况。
语法格式
if (条件表达式1) {
// 条件1为true时,执行代码块1
} else if (条件表达式2) {
// 条件1为false、条件2为true时,执行代码块2
} else if (条件表达式3) {
// 条件1、2为false、条件3为true时,执行代码块3
}
// 可继续添加多个else if
else {
// 所有条件都为false时,执行代码块n(可选)
}
核心规则
- 条件判断有顺序性,从上到下依次执行,满足一个条件后,后续所有 else if/else 都不再执行。
- else 为可选部分,若省略 else,当所有条件都不满足时,所有代码块都不会执行。
- 多个条件之间建议遵循范围从窄到宽的顺序,避免逻辑覆盖。
代码示例(结合 Scanner)
import java.util.Scanner;
public class IfElseIfDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的百分制成绩:");
int score = sc.nextInt();
// 多分支:按成绩范围分级评价
if (score >= 90 && score <= 100) {
System.out.println("成绩等级:优秀");
} else if (score >= 80 && score < 90) {
System.out.println("成绩等级:良好");
} else if (score >= 70 && score < 80) {
System.out.println("成绩等级:中等");
} else if (score >= 60 && score < 70) {
System.out.println("成绩等级:及格");
} else if (score >= 0 && score < 60) {
System.out.println("成绩等级:不及格");
} else {
System.out.println("你输入的成绩无效,请输入0-100的整数!");
}
sc.close();
}
}
4. if 语句的嵌套
适用场景
在一个 if/else 代码块中,再次编写 if/else if/else 语句,实现多层条件判断,处理复杂的逻辑场景。
语法格式
if (外层条件) {
// 外层条件为true时执行
if (内层条件) {
// 内层条件为true时执行
} else {
// 内层条件为false时执行
}
} else {
// 外层条件为false时执行
}
核心规则
- 嵌套层级不宜过多(建议不超过 3 层),否则代码可读性极差。
- 大括号
{}可以明确代码块的归属,避免嵌套时的逻辑混乱(强制推荐写大括号)。 - 内层 if 语句仅受外层 if 语句的条件控制,外层条件不满足时,内层 if 不会执行。
代码示例
import java.util.Scanner;
public class IfNestDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的性别(男/女):");
String gender = sc.next();
System.out.println("请输入你的年龄:");
int age = sc.nextInt();
// 嵌套if:先判断性别,再判断年龄
if (gender.equals("女")) {
if (age >= 20) {
System.out.println("女,已到法定结婚年龄");
} else {
System.out.println("女,未到法定结婚年龄");
}
} else if (gender.equals("男")) {
if (age >= 22) {
System.out.println("男,已到法定结婚年龄");
} else {
System.out.println("男,未到法定结婚年龄");
}
} else {
System.out.println("你输入的性别无效!");
}
sc.close();
}
}
四、if 语句核心注意事项
- 条件表达式类型:必须是boolean 类型(true/false),Java 不支持数值型条件(如
if(1)会编译报错),需通过比较 / 逻辑运算符得到 boolean 结果。 - 大括号的使用:即使代码块只有一行,也推荐书写大括号,避免因后续加代码导致的逻辑错误(如 if 后省略大括号,else 会匹配最近的 if)。
- 条件的顺序性:多分支 if-else if 中,条件判断有先后,范围小的条件要写在前面,否则会被范围大的条件覆盖(如先写
score>=60,再写score>=90,则 90 分的情况永远匹配不到后者)。 - 变量的作用域:在 if/else 代码块内定义的变量,仅在当前代码块内有效,外部无法访问(大括号是作用域的边界)。
- 空值判断:当判断字符串、对象是否相等时,先判断是否为 null,避免空指针异常(如
if (str != null && str.equals("Java")))。 - Scanner 的结合:通过 Scanner 获取用户输入的动态数据,作为 if 语句的条件表达式,实现交互式的条件判断,是基础阶段的核心使用场景。
五、顺序结构与 if 结构的结合使用
实际开发中,纯顺序结构或纯 if 结构极少出现,通常是顺序结构为基础,嵌套 if 选择结构,实现复杂逻辑,核心执行规则:
- 先按顺序执行 if 语句之前的代码(如变量定义、Scanner 获取输入);
- 执行 if 语句的条件判断,根据结果选择执行对应的代码块(代码块内仍按顺序执行);
- 按顺序执行 if 语句之后的后续代码。
代码示例
import java.util.Scanner;
public class SequenceIfDemo {
public static void main(String[] args) {
// 顺序结构:1.导包 2.创建Scanner 3.提示输入 4.获取数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入两个整数,用空格分隔:");
int a = sc.nextInt();
int b = sc.nextInt();
int max;
// 选择结构:判断并获取最大值
if (a > b) {
max = a;
} else {
max = b;
}
// 顺序结构:输出结果,关闭Scanner
System.out.println("两个数中的最大值是:" + max);
sc.close();
}
}