Java基础06~10

6 阅读28分钟

Java基础06:变量、常量、作用域 学习笔记

一、变量

1. 定义

变量是程序运行过程中值可以发生改变的量,是用来存储数据的内存空间标识,通过变量名可以访问和操作对应的内存区域。

2. 变量的三要素

  • 数据类型:限定变量能存储的数据种类(如 int、String、double 等),决定内存空间大小。
  • 变量名:符合 Java 命名规范的标识符,用于标识变量。
  • :变量存储的具体数据,需与数据类型匹配。

3. 变量的声明与赋值

声明格式
数据类型 变量名;
赋值格式
变量名 = 数值;
声明并赋值(常用)
数据类型 变量名 = 数值;
代码示例
// 先声明后赋值
int age;
age = 20;
// 声明并赋值
String name = "Java";
double score = 95.5;

4. Java 命名规范(变量 / 方法)

  • 由字母、数字、下划线_、美元符$组成,不能以数字开头
  • 严格区分大小写,如ageAge是两个不同变量。
  • 不能使用 Java 关键字(如 int、class、if 等)。
  • 采用驼峰命名法:首字母小写,后续单词首字母大写,如studentNamegetScore
  • 命名要做到见名知意,避免使用 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_AGEDEFAULT_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
值的可变性运行中可修改一旦赋值,不可修改
赋值时机可先声明后赋值,也可声明即赋值必须声明时直接赋值
命名规范小驼峰命名法,见名知意全大写,下划线分隔
内存特性随作用域结束回收,值动态变化随类 / 对象存在,值始终固定
适用场景存储程序运行中需要动态修改的数据存储程序中固定不变的配置值 / 常量

五、基础阶段核心注意点

  1. 局部变量是 Java 基础阶段最常用的变量,重点掌握声明 - 赋值 - 使用的流程,牢记 “先赋值再使用”。
  2. final 修饰的常量,不仅可以修饰基本数据类型,也可修饰引用数据类型(基础阶段暂不深入),核心特性均为 “值不可变”。
  3. 作用域的边界是大括号 {} ,一对 {} 代表一个独立的局部作用域,内部定义的变量外部无法访问。
  4. 变量的命名规范是 Java 编码的基础,从入门开始严格遵守,养成良好的编码习惯。
  5. 成员变量的默认值是基础考点,需熟记:int→0、double→0.0、boolean→false、String→null。

Java基础07:运算符 学习笔记

一、运算符概述

  1. 运算符是用于对常量变量进行运算操作的符号,通过运算符可以实现数据的计算、比较、赋值等操作。
  2. Java 运算符按功能可分为算术运算符赋值运算符比较运算符逻辑运算符自增自减运算符等,是 Java 基础编程的核心基础。
  3. 运算符操作的数称为操作数,单个操作数的为单目运算符,两个为双目运算符,三个为三目运算符(三元运算符)。

二、算术运算符

1. 基本算术运算符

运算符作用示例结果
+加法 / 字符串拼接10+20/"Java"+"学习"30/Java学习
-减法 / 取负20-10/-1010/-10
*乘法10*20200
/除法20/10/20/32/6(整数相除取整)
%取模(求余数)20%3/10%22/0

2. 关键注意点

  • 整数相除时,结果只保留整数部分,舍弃小数部分(无四舍五入);若需保留小数,需将其中一个操作数转为浮点型(如20.0/3)。
  • 取模运算的结果符号与被除数一致,如-20%3=-220%-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 + bint a=10; a+=20;30
-=减后赋值a = a - bint a=20; a-=10;10
*=乘后赋值a = a * bint a=10; a*=2;20
/=除后赋值a = a / bint a=20; a/=2;10
%=取模后赋值a = a % bint 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!=20true
>大于20>10true
<小于20<10false
>=大于等于10>=10true
<=小于等于10<=20true

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>5false
&逻辑与两边都为 true,结果才为 true; 左边为 false,右边仍执行10>20 & 10>5false
``短路或两边有一个为 true,结果就为 true; 左边为 true,右边不执行`10>510>20`true
``逻辑或两边有一个为 true,结果就为 true; 左边为 true,右边仍执行`10>510>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. 运算规则

  1. 先判断条件表达式的结果:

    1. 若为true,执行表达式 1,并将其结果作为整个三元运算的结果;
    2. 若为false,执行表达式 2,并将其结果作为整个三元运算的结果。
  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更大

八、运算符的优先级

  1. Java 中运算符的优先级决定了表达式的执行顺序,优先级高的先执行,优先级低的后执行。
  2. 核心优先级排序(从高到低): 括号 () > 自增自减 (++/--) > 算术运算符 (* / % > + -) > 比较运算符 > 逻辑运算符 (&& > ||) > 三元运算符 > 赋值运算符
  3. 开发中无需死记优先级,通过小括号 () 明确执行顺序,代码更易读(推荐做法)。

代码示例

// 优先级默认执行
int res1 = 10 + 20 * 3;
System.out.println(res1); //70(先乘后加)

// 括号改变执行顺序
int res2 = (10 + 20) * 3;
System.out.println(res2); //90(先加后乘)

九、基础阶段核心注意点

  1. 整数除法的取整特性和取模的符号规则是高频考点,需重点掌握。
  2. 自增自减的前置 / 后置区别是基础易错点,记住前置先算后用,后置先用后算
  3. 复合赋值运算符会自动类型转换,适合小范围数据类型(byte/short),普通赋值需手动强转。
  4. 开发中优先使用&&||,利用短路特性提升程序效率,避免&|的无效执行。
  5. 三元运算符可简化简单的 if-else 判断,嵌套使用时需注意可读性,复杂判断建议用 if-else。
  6. 避免因运算符优先级导致的逻辑错误,优先用小括号明确执行顺序。

Java基础补充:位运算符 学习笔记

位运算符是 Java 中直接对二进制位(bit) 进行操作的运算符,运算速度极快(底层直接操作内存),常用于底层开发、性能优化、加密算法等场景。

一、位运算符核心前提

  1. 操作对象:仅支持整数类型(byte、short、int、long),不能操作浮点数、布尔值等其他类型。
  2. 运算本质:将十进制数转换为补码(正数补码 = 原码,负数补码 = 反码 + 1)后,按位逐位计算,结果再转回十进制。
  3. 位的表示:以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 01005 = 0000 0101
      int b = 4 | 5; // 结果:0000 0101 → 5
      

3. 按位异或(^)

  • 规则:两个对应位相同为 0,不同为 1(同 0 异 1)。

  • 核心特性

    • 一个数异或自身等于 0:a ^ a = 0
    • 一个数异或 0 等于自身:a ^ 0 = a
    • 可交换、可结合(开发中常用于交换变量、简单加密)。
  • 代码示例

    • // 交换两个数(无需临时变量,经典技巧)
      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 01005 = 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无符号数处理、二进制解析-

四、开发中高频使用技巧

  1. 快速计算 2 的幂次:用1 << n代替Math.pow(2, n),速度更快(如1 << 10 = 1024)。
  2. 高效取余:对 2 的幂次取余(如a % 8),可用a & 7替代(仅适用于正数)。
  3. 交换变量:利用异或特性,无需临时变量(但可读性稍差,实际开发慎用)。
  4. 权限控制:用不同位表示不同权限(如第 0 位 = 查看,第 1 位 = 新增),通过位运算快速判断 / 设置权限。

五、核心注意点

  1. 位运算优先级:低于算术运算符,建议用括号明确优先级(如(a & b) + c)。
  2. 负数运算:必须先理解补码规则,否则易得出错误结果(尤其是右移和无符号右移)。
  3. 溢出问题:左移易导致数值溢出,需提前判断取值范围。
  4. 实际场景:日常业务开发中用得较少,主要集中在底层框架、性能优化、算法、硬件交互等领域。

Java基础09:流程控制

一、流程控制概述

Java 流程控制用于规范程序的执行顺序,核心分为顺序结构选择结构循环结构,而Scanner 类是实现程序与用户交互的核心工具,能获取键盘输入的各类数据,是流程控制中实现动态逻辑的基础,也是 P31 的核心讲解内容。

二、Scanner 类核心知识点

1. 类的作用

java.util.Scanner是 Java5 新增的 IO 工具类,专门用于获取用户键盘输入,支持字符串、整数、浮点型等多种数据类型的输入获取,是基础阶段实现用户交互的唯一方式。

2. 使用前置条件

必须先导入 Scanner 包,且导包语句需写在程序最上方,语法:

import java.util.Scanner; // 导入Scanner包,固定写法

3. 核心使用步骤(四步走)

  1. 创建 Scanner 对象:关联系统输入流,建立程序与键盘的连接;
  2. 判断输入(可选) :通过hasNextXxx()判断用户是否输入指定类型数据,避免程序报错;
  3. 获取输入:通过nextXxx()获取用户输入的具体数据;
  4. 关闭 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 使用核心注意点

  1. 导包位置import java.util.Scanner必须写在类定义之前,程序最上方,否则编译报错。
  2. 对象创建Scanner sc = new Scanner(System.in)为固定写法,System.in表示关联系统输入流。
  3. 方法匹配hasNextXxx()nextXxx()必须类型匹配,如hasNextInt()对应nextInt()
  4. 资源关闭:使用完毕后必须执行sc.close(),Scanner 属于 IO 流,不关闭会占用系统资源。
  5. 空白处理next()会自动忽略输入前的空白,且遇到空白立即停止取值,无法接收带空格的字符串。
  6. 换行符问题:若在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 对象可使用快捷键快速生成:

  1. 输入sc,按Tab键,快速生成Scanner sc = new Scanner(System.in);
  2. 输入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 语句

  1. 顺序结构:程序默认的执行结构,从上到下、从左到右依次执行每一行代码,无跳转、无分支。
  2. 选择结构:根据条件判断结果,选择执行不同的代码块,核心为if语句和switch语句(P32 重点讲 if)。
  3. 循环结构:根据循环条件,重复执行某一段代码,核心为forwhiledo-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) {
    // 条件1true时,执行代码块1
} else if (条件表达式2) {
    // 条件1false、条件2true时,执行代码块2
} else if (条件表达式3) {
    // 条件12false、条件3true时,执行代码块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 语句核心注意事项

  1. 条件表达式类型:必须是boolean 类型(true/false),Java 不支持数值型条件(如if(1)会编译报错),需通过比较 / 逻辑运算符得到 boolean 结果。
  2. 大括号的使用:即使代码块只有一行,也推荐书写大括号,避免因后续加代码导致的逻辑错误(如 if 后省略大括号,else 会匹配最近的 if)。
  3. 条件的顺序性:多分支 if-else if 中,条件判断有先后,范围小的条件要写在前面,否则会被范围大的条件覆盖(如先写score>=60,再写score>=90,则 90 分的情况永远匹配不到后者)。
  4. 变量的作用域:在 if/else 代码块内定义的变量,仅在当前代码块内有效,外部无法访问(大括号是作用域的边界)。
  5. 空值判断:当判断字符串、对象是否相等时,先判断是否为 null,避免空指针异常(如if (str != null && str.equals("Java")))。
  6. Scanner 的结合:通过 Scanner 获取用户输入的动态数据,作为 if 语句的条件表达式,实现交互式的条件判断,是基础阶段的核心使用场景。

五、顺序结构与 if 结构的结合使用

实际开发中,纯顺序结构或纯 if 结构极少出现,通常是顺序结构为基础,嵌套 if 选择结构,实现复杂逻辑,核心执行规则:

  1. 先按顺序执行 if 语句之前的代码(如变量定义、Scanner 获取输入);
  2. 执行 if 语句的条件判断,根据结果选择执行对应的代码块(代码块内仍按顺序执行);
  3. 按顺序执行 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();
    }
}