云计算百科
云计算领域专业知识百科平台

第33章 变量与常量:变量声明、作用域与final关键字

一、变量概述

1.1 什么是变量

在程序运行过程中,数据需要被存储、读取和修改。变量(Variable)就是程序中用于存储数据的一块命名内存空间。可以把变量理解为一个"带标签的容器"——标签是变量名,容器里存放的是具体的数值。当程序需要使用这个数值时,通过变量名即可访问;当需要改变这个数值时,也通过变量名进行赋值。

用生活中的例子来类比:一个停车场有若干个车位,每个车位有一个编号(如A12、B07)。当你把车停进去后,别人可以通过车位编号找到你的车。这里的"车位编号"相当于变量名,"车位"相当于内存空间,"车"相当于变量中存储的值。

#mermaid-svg-Nr7YHMXGQ83wid9m{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Nr7YHMXGQ83wid9m .error-icon{fill:#552222;}#mermaid-svg-Nr7YHMXGQ83wid9m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Nr7YHMXGQ83wid9m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Nr7YHMXGQ83wid9m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Nr7YHMXGQ83wid9m .marker.cross{stroke:#333333;}#mermaid-svg-Nr7YHMXGQ83wid9m svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Nr7YHMXGQ83wid9m p{margin:0;}#mermaid-svg-Nr7YHMXGQ83wid9m .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m .cluster-label text{fill:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m .cluster-label span{color:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m .cluster-label span p{background-color:transparent;}#mermaid-svg-Nr7YHMXGQ83wid9m .label text,#mermaid-svg-Nr7YHMXGQ83wid9m span{fill:#333;color:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m .node rect,#mermaid-svg-Nr7YHMXGQ83wid9m .node circle,#mermaid-svg-Nr7YHMXGQ83wid9m .node ellipse,#mermaid-svg-Nr7YHMXGQ83wid9m .node polygon,#mermaid-svg-Nr7YHMXGQ83wid9m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Nr7YHMXGQ83wid9m .rough-node .label text,#mermaid-svg-Nr7YHMXGQ83wid9m .node .label text,#mermaid-svg-Nr7YHMXGQ83wid9m .image-shape .label,#mermaid-svg-Nr7YHMXGQ83wid9m .icon-shape .label{text-anchor:middle;}#mermaid-svg-Nr7YHMXGQ83wid9m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Nr7YHMXGQ83wid9m .rough-node .label,#mermaid-svg-Nr7YHMXGQ83wid9m .node .label,#mermaid-svg-Nr7YHMXGQ83wid9m .image-shape .label,#mermaid-svg-Nr7YHMXGQ83wid9m .icon-shape .label{text-align:center;}#mermaid-svg-Nr7YHMXGQ83wid9m .node.clickable{cursor:pointer;}#mermaid-svg-Nr7YHMXGQ83wid9m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Nr7YHMXGQ83wid9m .arrowheadPath{fill:#333333;}#mermaid-svg-Nr7YHMXGQ83wid9m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Nr7YHMXGQ83wid9m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Nr7YHMXGQ83wid9m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Nr7YHMXGQ83wid9m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Nr7YHMXGQ83wid9m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Nr7YHMXGQ83wid9m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Nr7YHMXGQ83wid9m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Nr7YHMXGQ83wid9m .cluster text{fill:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m .cluster span{color:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Nr7YHMXGQ83wid9m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Nr7YHMXGQ83wid9m rect.text{fill:none;stroke-width:0;}#mermaid-svg-Nr7YHMXGQ83wid9m .icon-shape,#mermaid-svg-Nr7YHMXGQ83wid9m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Nr7YHMXGQ83wid9m .icon-shape p,#mermaid-svg-Nr7YHMXGQ83wid9m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Nr7YHMXGQ83wid9m .icon-shape .label rect,#mermaid-svg-Nr7YHMXGQ83wid9m .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Nr7YHMXGQ83wid9m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Nr7YHMXGQ83wid9m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Nr7YHMXGQ83wid9m :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

变量名

内存地址

存储的值

在Java中,每个变量都有三个核心属性:

属性说明示例
数据类型 决定变量能存储什么类型的值,以及占用多少内存 int、double、String
变量名 程序中引用该变量的标识符 age、studentName
值 实际存储的数据 25、"张三"

1.2 变量的本质:内存模型

从底层角度来看,声明一个变量的过程实际上是向JVM申请一块内存空间。以int age = 25;为例:

  • JVM在栈内存中分配4个字节的空间(int类型占4字节)
  • 将该内存地址与变量名age绑定
  • 将数值25以二进制补码形式写入这块内存
  • 内存空间Java虚拟机Java程序内存空间Java虚拟机Java程序#mermaid-svg-2faWJWAHC7DcVKcV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2faWJWAHC7DcVKcV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2faWJWAHC7DcVKcV .error-icon{fill:#552222;}#mermaid-svg-2faWJWAHC7DcVKcV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2faWJWAHC7DcVKcV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2faWJWAHC7DcVKcV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2faWJWAHC7DcVKcV .marker.cross{stroke:#333333;}#mermaid-svg-2faWJWAHC7DcVKcV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2faWJWAHC7DcVKcV p{margin:0;}#mermaid-svg-2faWJWAHC7DcVKcV .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2faWJWAHC7DcVKcV text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-2faWJWAHC7DcVKcV .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-2faWJWAHC7DcVKcV .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-2faWJWAHC7DcVKcV .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-2faWJWAHC7DcVKcV .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-2faWJWAHC7DcVKcV #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-2faWJWAHC7DcVKcV .sequenceNumber{fill:white;}#mermaid-svg-2faWJWAHC7DcVKcV #sequencenumber{fill:#333;}#mermaid-svg-2faWJWAHC7DcVKcV #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-2faWJWAHC7DcVKcV .messageText{fill:#333;stroke:none;}#mermaid-svg-2faWJWAHC7DcVKcV .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2faWJWAHC7DcVKcV .labelText,#mermaid-svg-2faWJWAHC7DcVKcV .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-2faWJWAHC7DcVKcV .loopText,#mermaid-svg-2faWJWAHC7DcVKcV .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-2faWJWAHC7DcVKcV .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-2faWJWAHC7DcVKcV .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-2faWJWAHC7DcVKcV .noteText,#mermaid-svg-2faWJWAHC7DcVKcV .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-2faWJWAHC7DcVKcV .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2faWJWAHC7DcVKcV .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2faWJWAHC7DcVKcV .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2faWJWAHC7DcVKcV .actorPopupMenu{position:absolute;}#mermaid-svg-2faWJWAHC7DcVKcV .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-2faWJWAHC7DcVKcV .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2faWJWAHC7DcVKcV .actor-man circle,#mermaid-svg-2faWJWAHC7DcVKcV line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-2faWJWAHC7DcVKcV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}int age = 25分配4字节空间(地址0x1000)写入值25(0x00000019)绑定 age ->> 0x1000

    理解变量的内存模型有助于理解后续的作用域、生命周期和垃圾回收等概念。


    二、变量的声明与初始化

    2.1 声明语法

    Java是强类型语言,每个变量在使用前必须先声明其类型。声明变量的基本语法为:

    数据类型 变量名;

    也可以在声明的同时赋予初始值:

    数据类型 变量名 = 初始值;

    以下是各种数据类型的变量声明示例:

    // 基本类型变量
    int count = 100;
    double price = 29.99;
    boolean isActive = true;
    char grade = 'A';
    long timestamp = 1692000000000L;
    float pi = 3.14f;

    // 引用类型变量
    String name = "张三";
    int[] scores = {85, 90, 78, 92};
    List<String> names = new ArrayList<>();

    2.2 多变量声明

    Java允许在一行中声明多个同类型变量:

    // 一行声明多个变量
    int a, b, c;

    // 声明并分别初始化
    int x = 1, y = 2, z = 3;

    // 部分初始化(不推荐)
    int m = 10, n, p = 20; // n未初始化

    虽然语法上允许,但从代码可读性考虑,建议每行只声明一个变量:

    // 推荐写法
    int x = 1;
    int y = 2;
    int z = 3;

    2.3 声明与赋值的分离

    变量的声明和赋值可以分两步进行:

    // 第一步:声明
    String message;

    // 第二步:赋值(必须在首次使用之前)
    message = "Hello, Java!";

    System.out.println(message); // 输出:Hello, Java!

    需要注意的是,局部变量在赋值之前不能使用,否则编译器会报错:

    int result;
    System.out.println(result); // 编译错误:variable result might not have been initialized


    三、变量命名规范

    3.1 Java标识符规则

    变量名属于Java标识符(Identifier),必须遵循以下规则:

    规则说明合法示例非法示例
    首字符 字母、下划线_或美元符号$ name、_value、$price 1name、@count
    后续字符 字母、数字、下划线、美元符号 age2、first_name name@、user id
    大小写敏感 age和Age是不同的变量 age = 10; Age = 20 –
    不能使用关键字 不能用int、class等保留字 – int class = 1;
    不能使用保留字 goto、const等 – int goto = 2;

    3.2 驼峰命名法(Camel Case)

    Java社区广泛采用驼峰命名法,具体规则如下:

    // 小驼峰命名法(lowerCamelCase)—— 用于变量名和方法名
    String studentName; // 正确
    int totalScore; // 正确
    boolean isGraduated; // 正确

    // 错误示范
    String student_name; // 不符合Java惯例(虽然语法合法)
    String StudentName; // 与类名混淆,不推荐

    // 大驼峰命名法(UpperCamelCase)—— 用于类名和接口名
    class StudentManager {}
    interface DataProcessor {}

    3.3 命名的艺术:见名知意

    一个好的变量名应该能够清晰传达其用途和含义,让代码像自然语言一样易读:

    // ❌ 不好的命名——含义模糊
    int d; // d是什么?天数?距离?
    String s; // s是什么?学生?字符串?
    boolean f; // f是什么?标志?找到了?

    // ✅ 好的命名——见名知意
    int daysSinceRegistration; // 一目了然:注册以来的天数
    String studentFullName; // 清晰表达:学生全名
    boolean hasPermission; // 语义明确:是否拥有权限

    好的命名遵循以下原则:

    • 使用完整的单词,避免无意义的缩写(address而非addr)
    • 布尔变量以is、has、can、should开头
    • 集合类变量使用复数形式(students、orderItems)
    • 避免使用拼音,使用准确的英文词汇
    • 避免单字母变量,除非是循环中的临时变量(i、j、k)

    四、变量的分类

    Java中的变量根据声明位置和修饰符的不同,可以分为三大类:局部变量、实例变量(成员变量)和静态变量(类变量)。

    4.1 分类对比总览

    #mermaid-svg-9YjYA660CqQLr7vE{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9YjYA660CqQLr7vE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9YjYA660CqQLr7vE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9YjYA660CqQLr7vE .error-icon{fill:#552222;}#mermaid-svg-9YjYA660CqQLr7vE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9YjYA660CqQLr7vE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9YjYA660CqQLr7vE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9YjYA660CqQLr7vE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9YjYA660CqQLr7vE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9YjYA660CqQLr7vE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9YjYA660CqQLr7vE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9YjYA660CqQLr7vE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9YjYA660CqQLr7vE .marker.cross{stroke:#333333;}#mermaid-svg-9YjYA660CqQLr7vE svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9YjYA660CqQLr7vE p{margin:0;}#mermaid-svg-9YjYA660CqQLr7vE .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-9YjYA660CqQLr7vE .cluster-label text{fill:#333;}#mermaid-svg-9YjYA660CqQLr7vE .cluster-label span{color:#333;}#mermaid-svg-9YjYA660CqQLr7vE .cluster-label span p{background-color:transparent;}#mermaid-svg-9YjYA660CqQLr7vE .label text,#mermaid-svg-9YjYA660CqQLr7vE span{fill:#333;color:#333;}#mermaid-svg-9YjYA660CqQLr7vE .node rect,#mermaid-svg-9YjYA660CqQLr7vE .node circle,#mermaid-svg-9YjYA660CqQLr7vE .node ellipse,#mermaid-svg-9YjYA660CqQLr7vE .node polygon,#mermaid-svg-9YjYA660CqQLr7vE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9YjYA660CqQLr7vE .rough-node .label text,#mermaid-svg-9YjYA660CqQLr7vE .node .label text,#mermaid-svg-9YjYA660CqQLr7vE .image-shape .label,#mermaid-svg-9YjYA660CqQLr7vE .icon-shape .label{text-anchor:middle;}#mermaid-svg-9YjYA660CqQLr7vE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9YjYA660CqQLr7vE .rough-node .label,#mermaid-svg-9YjYA660CqQLr7vE .node .label,#mermaid-svg-9YjYA660CqQLr7vE .image-shape .label,#mermaid-svg-9YjYA660CqQLr7vE .icon-shape .label{text-align:center;}#mermaid-svg-9YjYA660CqQLr7vE .node.clickable{cursor:pointer;}#mermaid-svg-9YjYA660CqQLr7vE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9YjYA660CqQLr7vE .arrowheadPath{fill:#333333;}#mermaid-svg-9YjYA660CqQLr7vE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9YjYA660CqQLr7vE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9YjYA660CqQLr7vE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9YjYA660CqQLr7vE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9YjYA660CqQLr7vE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9YjYA660CqQLr7vE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9YjYA660CqQLr7vE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9YjYA660CqQLr7vE .cluster text{fill:#333;}#mermaid-svg-9YjYA660CqQLr7vE .cluster span{color:#333;}#mermaid-svg-9YjYA660CqQLr7vE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9YjYA660CqQLr7vE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9YjYA660CqQLr7vE rect.text{fill:none;stroke-width:0;}#mermaid-svg-9YjYA660CqQLr7vE .icon-shape,#mermaid-svg-9YjYA660CqQLr7vE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9YjYA660CqQLr7vE .icon-shape p,#mermaid-svg-9YjYA660CqQLr7vE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9YjYA660CqQLr7vE .icon-shape .label rect,#mermaid-svg-9YjYA660CqQLr7vE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9YjYA660CqQLr7vE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9YjYA660CqQLr7vE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9YjYA660CqQLr7vE :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Java变量

    按声明位置分类

    局部变量 local variable

    成员变量 member variable

    实例变量 instance variable

    静态变量 static variable / 类变量 class variable

    方法内部声明

    代码块内部声明

    方法参数

    类中声明 无static修饰

    类中声明 有static修饰

    4.2 局部变量(Local Variables)

    局部变量是在方法、构造器或代码块内部声明的变量。它们只在声明它们的代码块内有效,出了代码块就无法访问。

    public class LocalVariableDemo {

    public void calculateSum() {
    // a和b是局部变量——在方法内部声明
    int a = 10;
    int b = 20;
    int sum = a + b; // sum也是局部变量

    System.out.println("和:" + sum);
    }

    public void printNumbers() {
    // 代码块内的局部变量
    for (int i = 0; i < 5; i++) { // i是循环局部变量
    System.out.println(i);
    }
    // System.out.println(i); // 编译错误:i在此处不可见
    }

    public void greet(String name) { // name是方法参数,也属于局部变量
    String greeting = "你好," + name;
    System.out.println(greeting);
    }
    }

    局部变量的特点:

    特点说明
    存储位置 栈内存(Stack)
    默认值 没有默认值,必须手动初始化后才能使用
    生命周期 从声明处开始,到所在代码块结束
    访问修饰符 不能使用public/private/protected等修饰符
    线程安全 每个线程拥有独立的栈帧,天然线程安全

    4.3 实例变量(Instance Variables / 成员变量)

    实例变量是在类内部、方法外部声明的、没有static修饰的变量。每个类的实例(对象)都有自己的一份实例变量副本。

    public class Student {
    // 实例变量——属于每个Student对象
    private String name;
    private int age;
    private String studentId;

    public Student(String name, int age, String studentId) {
    this.name = name;
    this.age = age;
    this.studentId = studentId;
    }

    public void display() {
    System.out.println(name + "," + age + "岁,学号:" + studentId);
    }

    public static void main(String[] args) {
    Student s1 = new Student("张三", 20, "2024001");
    Student s2 = new Student("李四", 21, "2024002");

    s1.display(); // 张三,20岁,学号:2024001
    s2.display(); // 李四,21岁,学号:2024002
    // s1和s2拥有各自独立的name、age、studentId副本
    }
    }

    #mermaid-svg-05LW9fJboUBFYGuC{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-05LW9fJboUBFYGuC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-05LW9fJboUBFYGuC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-05LW9fJboUBFYGuC .error-icon{fill:#552222;}#mermaid-svg-05LW9fJboUBFYGuC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-05LW9fJboUBFYGuC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-05LW9fJboUBFYGuC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-05LW9fJboUBFYGuC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-05LW9fJboUBFYGuC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-05LW9fJboUBFYGuC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-05LW9fJboUBFYGuC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-05LW9fJboUBFYGuC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-05LW9fJboUBFYGuC .marker.cross{stroke:#333333;}#mermaid-svg-05LW9fJboUBFYGuC svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-05LW9fJboUBFYGuC p{margin:0;}#mermaid-svg-05LW9fJboUBFYGuC .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-05LW9fJboUBFYGuC .cluster-label text{fill:#333;}#mermaid-svg-05LW9fJboUBFYGuC .cluster-label span{color:#333;}#mermaid-svg-05LW9fJboUBFYGuC .cluster-label span p{background-color:transparent;}#mermaid-svg-05LW9fJboUBFYGuC .label text,#mermaid-svg-05LW9fJboUBFYGuC span{fill:#333;color:#333;}#mermaid-svg-05LW9fJboUBFYGuC .node rect,#mermaid-svg-05LW9fJboUBFYGuC .node circle,#mermaid-svg-05LW9fJboUBFYGuC .node ellipse,#mermaid-svg-05LW9fJboUBFYGuC .node polygon,#mermaid-svg-05LW9fJboUBFYGuC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-05LW9fJboUBFYGuC .rough-node .label text,#mermaid-svg-05LW9fJboUBFYGuC .node .label text,#mermaid-svg-05LW9fJboUBFYGuC .image-shape .label,#mermaid-svg-05LW9fJboUBFYGuC .icon-shape .label{text-anchor:middle;}#mermaid-svg-05LW9fJboUBFYGuC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-05LW9fJboUBFYGuC .rough-node .label,#mermaid-svg-05LW9fJboUBFYGuC .node .label,#mermaid-svg-05LW9fJboUBFYGuC .image-shape .label,#mermaid-svg-05LW9fJboUBFYGuC .icon-shape .label{text-align:center;}#mermaid-svg-05LW9fJboUBFYGuC .node.clickable{cursor:pointer;}#mermaid-svg-05LW9fJboUBFYGuC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-05LW9fJboUBFYGuC .arrowheadPath{fill:#333333;}#mermaid-svg-05LW9fJboUBFYGuC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-05LW9fJboUBFYGuC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-05LW9fJboUBFYGuC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-05LW9fJboUBFYGuC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-05LW9fJboUBFYGuC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-05LW9fJboUBFYGuC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-05LW9fJboUBFYGuC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-05LW9fJboUBFYGuC .cluster text{fill:#333;}#mermaid-svg-05LW9fJboUBFYGuC .cluster span{color:#333;}#mermaid-svg-05LW9fJboUBFYGuC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-05LW9fJboUBFYGuC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-05LW9fJboUBFYGuC rect.text{fill:none;stroke-width:0;}#mermaid-svg-05LW9fJboUBFYGuC .icon-shape,#mermaid-svg-05LW9fJboUBFYGuC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-05LW9fJboUBFYGuC .icon-shape p,#mermaid-svg-05LW9fJboUBFYGuC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-05LW9fJboUBFYGuC .icon-shape .label rect,#mermaid-svg-05LW9fJboUBFYGuC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-05LW9fJboUBFYGuC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-05LW9fJboUBFYGuC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-05LW9fJboUBFYGuC :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    栈内存

    堆内存

    Student对象 s1

    name = 张三

    age = 20

    studentId = 2024001

    Student对象 s2

    name = 李四

    age = 21

    studentId = 2024002

    s1 引用

    s2 引用

    实例变量的特点:

    特点说明
    存储位置 堆内存(Heap),随对象分配
    默认值 有默认值(int为0,boolean为false,引用类型为null)
    生命周期 随对象的创建而创建,随对象的销毁而销毁
    访问修饰符 可以使用public/protected/private/默认
    访问方式 通过对象引用.变量名访问

    4.4 静态变量(Static Variables / 类变量)

    静态变量是用static关键字修饰的、在类内部声明的变量。它与类绑定而非与对象绑定——整个类只有一份静态变量的副本,被所有实例共享。

    public class Counter {
    // 实例变量——每个对象独立
    private int instanceCount = 0;

    // 静态变量——所有对象共享
    private static int totalCount = 0;

    public Counter() {
    instanceCount++;
    totalCount++;
    }

    public void display() {
    System.out.println("实例计数:" + instanceCount);
    System.out.println("总计计数:" + totalCount);
    }

    public static void main(String[] args) {
    Counter c1 = new Counter();
    Counter c2 = new Counter();
    Counter c3 = new Counter();

    c1.display(); // 实例计数:1,总计计数:3
    c2.display(); // 实例计数:1,总计计数:3
    c3.display(); // 实例计数:1,总计计数:3
    // 注意:每个对象的instanceCount都是1(独立),
    // 而totalCount是3(共享)
    }
    }

    #mermaid-svg-lmLWssxbIoaDZT6i{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lmLWssxbIoaDZT6i .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lmLWssxbIoaDZT6i .error-icon{fill:#552222;}#mermaid-svg-lmLWssxbIoaDZT6i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lmLWssxbIoaDZT6i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lmLWssxbIoaDZT6i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lmLWssxbIoaDZT6i .marker.cross{stroke:#333333;}#mermaid-svg-lmLWssxbIoaDZT6i svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lmLWssxbIoaDZT6i p{margin:0;}#mermaid-svg-lmLWssxbIoaDZT6i .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-lmLWssxbIoaDZT6i .cluster-label text{fill:#333;}#mermaid-svg-lmLWssxbIoaDZT6i .cluster-label span{color:#333;}#mermaid-svg-lmLWssxbIoaDZT6i .cluster-label span p{background-color:transparent;}#mermaid-svg-lmLWssxbIoaDZT6i .label text,#mermaid-svg-lmLWssxbIoaDZT6i span{fill:#333;color:#333;}#mermaid-svg-lmLWssxbIoaDZT6i .node rect,#mermaid-svg-lmLWssxbIoaDZT6i .node circle,#mermaid-svg-lmLWssxbIoaDZT6i .node ellipse,#mermaid-svg-lmLWssxbIoaDZT6i .node polygon,#mermaid-svg-lmLWssxbIoaDZT6i .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lmLWssxbIoaDZT6i .rough-node .label text,#mermaid-svg-lmLWssxbIoaDZT6i .node .label text,#mermaid-svg-lmLWssxbIoaDZT6i .image-shape .label,#mermaid-svg-lmLWssxbIoaDZT6i .icon-shape .label{text-anchor:middle;}#mermaid-svg-lmLWssxbIoaDZT6i .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lmLWssxbIoaDZT6i .rough-node .label,#mermaid-svg-lmLWssxbIoaDZT6i .node .label,#mermaid-svg-lmLWssxbIoaDZT6i .image-shape .label,#mermaid-svg-lmLWssxbIoaDZT6i .icon-shape .label{text-align:center;}#mermaid-svg-lmLWssxbIoaDZT6i .node.clickable{cursor:pointer;}#mermaid-svg-lmLWssxbIoaDZT6i .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lmLWssxbIoaDZT6i .arrowheadPath{fill:#333333;}#mermaid-svg-lmLWssxbIoaDZT6i .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lmLWssxbIoaDZT6i .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lmLWssxbIoaDZT6i .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lmLWssxbIoaDZT6i .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lmLWssxbIoaDZT6i .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lmLWssxbIoaDZT6i .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lmLWssxbIoaDZT6i .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lmLWssxbIoaDZT6i .cluster text{fill:#333;}#mermaid-svg-lmLWssxbIoaDZT6i .cluster span{color:#333;}#mermaid-svg-lmLWssxbIoaDZT6i div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lmLWssxbIoaDZT6i .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lmLWssxbIoaDZT6i rect.text{fill:none;stroke-width:0;}#mermaid-svg-lmLWssxbIoaDZT6i .icon-shape,#mermaid-svg-lmLWssxbIoaDZT6i .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lmLWssxbIoaDZT6i .icon-shape p,#mermaid-svg-lmLWssxbIoaDZT6i .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lmLWssxbIoaDZT6i .icon-shape .label rect,#mermaid-svg-lmLWssxbIoaDZT6i .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lmLWssxbIoaDZT6i .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lmLWssxbIoaDZT6i .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lmLWssxbIoaDZT6i :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    堆内存

    方法区/元空间

    静态变量 totalCount = 3

    Counter对象 c1

    instanceCount = 1

    Counter对象 c2

    instanceCount = 1

    Counter对象 c3

    instanceCount = 1

    静态变量的特点:

    特点说明
    存储位置 方法区(Method Area)/ 元空间(Metaspace,JDK 8+)
    默认值 有默认值(与实例变量相同)
    生命周期 类加载时创建,类卸载时销毁
    访问方式 类名.变量名(推荐)或对象引用.变量名(不推荐)
    共享性 所有实例共享同一个值

    4.5 三种变量的全面对比

    比较维度局部变量实例变量静态变量
    声明位置 方法/代码块内 类内、方法外、无static 类内、方法外、有static
    存储位置 栈内存 堆内存 方法区/元空间
    默认值 无,必须初始化 有 有
    生命周期 代码块执行期间 与对象相同 与类相同
    访问修饰符 不能使用 可以使用 可以使用
    归属 方法/代码块 对象实例 类本身
    线程安全 天然安全 不安全 不安全(需同步)
    访问方式 直接使用 对象.变量名 类名.变量名

    五、变量的作用域

    5.1 作用域的概念

    作用域(Scope)是指变量在程序中有效的范围。在Java中,变量的作用域由**声明它的花括号{}**决定——变量从声明的位置开始,到包含它的代码块结束为止都是有效的。

    #mermaid-svg-t61Z3C7qnWKeR3iv{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-t61Z3C7qnWKeR3iv .error-icon{fill:#552222;}#mermaid-svg-t61Z3C7qnWKeR3iv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-t61Z3C7qnWKeR3iv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-t61Z3C7qnWKeR3iv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-t61Z3C7qnWKeR3iv .marker.cross{stroke:#333333;}#mermaid-svg-t61Z3C7qnWKeR3iv svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-t61Z3C7qnWKeR3iv p{margin:0;}#mermaid-svg-t61Z3C7qnWKeR3iv .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv .cluster-label text{fill:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv .cluster-label span{color:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv .cluster-label span p{background-color:transparent;}#mermaid-svg-t61Z3C7qnWKeR3iv .label text,#mermaid-svg-t61Z3C7qnWKeR3iv span{fill:#333;color:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv .node rect,#mermaid-svg-t61Z3C7qnWKeR3iv .node circle,#mermaid-svg-t61Z3C7qnWKeR3iv .node ellipse,#mermaid-svg-t61Z3C7qnWKeR3iv .node polygon,#mermaid-svg-t61Z3C7qnWKeR3iv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-t61Z3C7qnWKeR3iv .rough-node .label text,#mermaid-svg-t61Z3C7qnWKeR3iv .node .label text,#mermaid-svg-t61Z3C7qnWKeR3iv .image-shape .label,#mermaid-svg-t61Z3C7qnWKeR3iv .icon-shape .label{text-anchor:middle;}#mermaid-svg-t61Z3C7qnWKeR3iv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-t61Z3C7qnWKeR3iv .rough-node .label,#mermaid-svg-t61Z3C7qnWKeR3iv .node .label,#mermaid-svg-t61Z3C7qnWKeR3iv .image-shape .label,#mermaid-svg-t61Z3C7qnWKeR3iv .icon-shape .label{text-align:center;}#mermaid-svg-t61Z3C7qnWKeR3iv .node.clickable{cursor:pointer;}#mermaid-svg-t61Z3C7qnWKeR3iv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-t61Z3C7qnWKeR3iv .arrowheadPath{fill:#333333;}#mermaid-svg-t61Z3C7qnWKeR3iv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-t61Z3C7qnWKeR3iv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-t61Z3C7qnWKeR3iv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-t61Z3C7qnWKeR3iv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-t61Z3C7qnWKeR3iv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-t61Z3C7qnWKeR3iv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-t61Z3C7qnWKeR3iv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-t61Z3C7qnWKeR3iv .cluster text{fill:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv .cluster span{color:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-t61Z3C7qnWKeR3iv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-t61Z3C7qnWKeR3iv rect.text{fill:none;stroke-width:0;}#mermaid-svg-t61Z3C7qnWKeR3iv .icon-shape,#mermaid-svg-t61Z3C7qnWKeR3iv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-t61Z3C7qnWKeR3iv .icon-shape p,#mermaid-svg-t61Z3C7qnWKeR3iv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-t61Z3C7qnWKeR3iv .icon-shape .label rect,#mermaid-svg-t61Z3C7qnWKeR3iv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-t61Z3C7qnWKeR3iv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-t61Z3C7qnWKeR3iv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-t61Z3C7qnWKeR3iv :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    作用域层级

    类作用域 Class Scope

    方法作用域 Method Scope

    块作用域 Block Scope

    实例变量和静态变量 整个类内可见

    方法参数和方法内局部变量 整个方法内可见

    代码块内声明的变量 仅块内可见

    5.2 块级作用域

    在一个花括号{}内声明的变量,其作用域仅限该花括号内部:

    public class ScopeDemo {
    // 类作用域——instanceVar在整个类内可见
    private int instanceVar = 100;

    public void methodScope() {
    // 方法作用域——methodVar在整个方法内可见
    int methodVar = 200;

    if (methodVar > 100) {
    // 块作用域——blockVar仅在if块内可见
    int blockVar = 300;
    System.out.println(blockVar); // 可以访问
    System.out.println(methodVar); // 可以访问
    System.out.println(instanceVar); // 可以访问
    }

    System.out.println(methodVar); // 可以访问
    System.out.println(instanceVar); // 可以访问
    // System.out.println(blockVar); // 编译错误!blockVar已超出作用域
    }
    }

    5.3 作用域嵌套与变量遮蔽

    当内层作用域声明了与外层作用域同名的变量时,会发生变量遮蔽(Variable Shadowing)——内层变量会"遮蔽"外层变量:

    public class ShadowingDemo {
    private int value = 10; // 实例变量

    public void test() {
    int value = 20; // 局部变量,遮蔽了实例变量

    System.out.println(value); // 输出20(局部变量)
    System.out.println(this.value); // 输出10(通过this访问实例变量)

    {
    int value = 30; // 编译错误!
    // 不能在嵌套块中声明与外部局部变量同名的变量
    }
    }
    }

    重要规则:

    • 局部变量可以遮蔽实例变量(通过this关键字仍然可以访问实例变量)
    • 方法参数可以遮蔽实例变量
    • 同一方法内的嵌套代码块不能声明与外层局部变量同名的变量(编译错误)

    5.4 循环中的作用域

    循环变量有特殊的作用域规则:

    // for循环中声明的变量——作用域仅限于for循环体
    for (int i = 0; i < 5; i++) {
    System.out.println(i); // 可以访问
    }
    // System.out.println(i); // 编译错误:i已超出作用域

    // 不同循环可以使用相同的变量名——因为作用域不重叠
    for (int i = 0; i < 3; i++) {
    System.out.println("第一个循环:" + i);
    }
    for (int i = 0; i < 3; i++) { // 合法的,新的作用域
    System.out.println("第二个循环:" + i);
    }

    // while循环中的变量——作用域是包含while的整个代码块
    {
    int j = 0;
    while (j < 5) {
    System.out.println(j);
    j++;
    }
    System.out.println("最终:" + j); // 可以访问,输出5
    }

    5.5 作用域最佳实践

    // ❌ 不推荐:变量作用域过大
    public void badExample() {
    String result; // 在方法开始就声明
    // … 50行代码 …
    result = computeResult(); // 实际使用时才赋值
    // … 更多代码 …
    }

    // ✅ 推荐:最小化变量作用域
    public void goodExample() {
    // … 其他代码 …
    String result = computeResult(); // 在第一次使用时才声明
    // … 使用result的代码 …
    }

    **原则:变量应该在尽可能小的作用域内声明,在使用前才声明。**这样做的好处包括提高代码可读性、减少命名冲突、降低出错概率。


    六、变量的生命周期

    6.1 生命周期的三个阶段

    变量的生命周期是指变量从创建到销毁的整个过程,分为三个阶段:

    #mermaid-svg-lDEacyhI6yVpvvA3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lDEacyhI6yVpvvA3 .error-icon{fill:#552222;}#mermaid-svg-lDEacyhI6yVpvvA3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lDEacyhI6yVpvvA3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lDEacyhI6yVpvvA3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lDEacyhI6yVpvvA3 .marker.cross{stroke:#333333;}#mermaid-svg-lDEacyhI6yVpvvA3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lDEacyhI6yVpvvA3 p{margin:0;}#mermaid-svg-lDEacyhI6yVpvvA3 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-lDEacyhI6yVpvvA3 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-lDEacyhI6yVpvvA3 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-lDEacyhI6yVpvvA3 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-lDEacyhI6yVpvvA3 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-lDEacyhI6yVpvvA3 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-lDEacyhI6yVpvvA3 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-lDEacyhI6yVpvvA3 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-lDEacyhI6yVpvvA3 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-lDEacyhI6yVpvvA3 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-lDEacyhI6yVpvvA3 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-lDEacyhI6yVpvvA3 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-lDEacyhI6yVpvvA3 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-lDEacyhI6yVpvvA3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lDEacyhI6yVpvvA3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lDEacyhI6yVpvvA3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lDEacyhI6yVpvvA3 .edgeLabel .label text{fill:#333;}#mermaid-svg-lDEacyhI6yVpvvA3 .label div .edgeLabel{color:#333;}#mermaid-svg-lDEacyhI6yVpvvA3 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-lDEacyhI6yVpvvA3 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-lDEacyhI6yVpvvA3 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-lDEacyhI6yVpvvA3 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-lDEacyhI6yVpvvA3 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-lDEacyhI6yVpvvA3 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lDEacyhI6yVpvvA3 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lDEacyhI6yVpvvA3 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lDEacyhI6yVpvvA3 .cluster-label,#mermaid-svg-lDEacyhI6yVpvvA3 .nodeLabel{color:#131300;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-lDEacyhI6yVpvvA3 .note-edge{stroke-dasharray:5;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-note text{fill:black;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagram .edgeLabel{color:red;}#mermaid-svg-lDEacyhI6yVpvvA3 #dependencyStart,#mermaid-svg-lDEacyhI6yVpvvA3 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-lDEacyhI6yVpvvA3 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lDEacyhI6yVpvvA3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    读取/修改

    垃圾回收

    声明/创建

    使用中

    超出作用域

    等待GC

    分配内存空间\\n赋予初始值

    程序读写变量

    变量不再可达

    由GC判断并回收

    6.2 不同类型变量的生命周期

    public class LifecycleDemo {
    // 静态变量:类加载时创建,程序结束时销毁(最长)
    private static int staticVar = initStatic();

    // 实例变量:对象创建时创建,对象被GC回收时销毁
    private int instanceVar = initInstance();

    static {
    System.out.println("[静态变量] 类加载时初始化");
    }

    public void method() {
    // 局部变量:方法调用时创建,方法返回时销毁
    int localVar = 10;
    System.out.println("[局部变量] 方法执行时存在");
    } // localVar在此处销毁

    private static int initStatic() {
    System.out.println("初始化静态变量");
    return 100;
    }

    private int initInstance() {
    System.out.println("初始化实例变量");
    return 200;
    }

    public static void main(String[] args) {
    System.out.println("— main方法开始 —");
    LifecycleDemo demo = new LifecycleDemo();
    demo.method();
    System.out.println("— main方法结束 —");
    }
    }

    输出顺序:

    初始化静态变量
    — main方法开始 —
    初始化实例变量
    [局部变量] 方法执行时存在
    — main方法结束 —

    6.3 垃圾回收与变量

    Java的内存管理由垃圾回收器(Garbage Collector, GC)自动完成。GC的基本原理是:当一个对象不再被任何变量引用时,它就变成了垃圾回收的候选对象。

    public class GCDemo {
    public static void main(String[] args) {
    // obj引用一个String对象
    String obj = new String("Hello");

    // obj仍然引用该对象——对象不可被回收
    System.out.println(obj);

    // 将obj设为null,断开引用
    obj = null;

    // 原来的String对象现在没有引用指向它——可以被GC回收
    // (实际回收时机由JVM决定,不一定是立即回收)

    // 作用域自然结束——变量超出作用域后,引用自动消失
    {
    String temp = new String("World");
    System.out.println(temp);
    } // temp超出作用域,"World"对象可以被回收

    // 提示JVM进行垃圾回收(不保证立即执行)
    System.gc();
    }
    }

    垃圾回收器堆中对象变量引用垃圾回收器堆中对象变量引用#mermaid-svg-tTaKvTzIINsMH8mO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tTaKvTzIINsMH8mO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tTaKvTzIINsMH8mO .error-icon{fill:#552222;}#mermaid-svg-tTaKvTzIINsMH8mO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tTaKvTzIINsMH8mO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tTaKvTzIINsMH8mO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tTaKvTzIINsMH8mO .marker.cross{stroke:#333333;}#mermaid-svg-tTaKvTzIINsMH8mO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tTaKvTzIINsMH8mO p{margin:0;}#mermaid-svg-tTaKvTzIINsMH8mO .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-tTaKvTzIINsMH8mO text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-tTaKvTzIINsMH8mO .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-tTaKvTzIINsMH8mO .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-tTaKvTzIINsMH8mO .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-tTaKvTzIINsMH8mO .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-tTaKvTzIINsMH8mO #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-tTaKvTzIINsMH8mO .sequenceNumber{fill:white;}#mermaid-svg-tTaKvTzIINsMH8mO #sequencenumber{fill:#333;}#mermaid-svg-tTaKvTzIINsMH8mO #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-tTaKvTzIINsMH8mO .messageText{fill:#333;stroke:none;}#mermaid-svg-tTaKvTzIINsMH8mO .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-tTaKvTzIINsMH8mO .labelText,#mermaid-svg-tTaKvTzIINsMH8mO .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-tTaKvTzIINsMH8mO .loopText,#mermaid-svg-tTaKvTzIINsMH8mO .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-tTaKvTzIINsMH8mO .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-tTaKvTzIINsMH8mO .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-tTaKvTzIINsMH8mO .noteText,#mermaid-svg-tTaKvTzIINsMH8mO .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-tTaKvTzIINsMH8mO .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-tTaKvTzIINsMH8mO .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-tTaKvTzIINsMH8mO .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-tTaKvTzIINsMH8mO .actorPopupMenu{position:absolute;}#mermaid-svg-tTaKvTzIINsMH8mO .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-tTaKvTzIINsMH8mO .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-tTaKvTzIINsMH8mO .actor-man circle,#mermaid-svg-tTaKvTzIINsMH8mO line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-tTaKvTzIINsMH8mO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}对象被引用,存活对象不可达内存释放String obj = new String("Hello")obj = null(断开引用)标记为垃圾回收内存


    七、常量概述

    7.1 什么是常量

    常量(Constant)是指在程序运行期间其值不能被修改的变量。在Java中,使用final关键字来定义常量。

    final double PI = 3.1415926535;
    final int MAX_USERS = 1000;
    final String APP_NAME = "教务管理系统";

    常量的核心语义是:一旦赋值,永不改变。任何试图修改常量值的操作都会导致编译错误:

    final int MAX = 100;
    MAX = 200; // 编译错误:cannot assign a value to final variable

    7.2 变量与常量的本质区别

    #mermaid-svg-CR3HslHAMOnawitr{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CR3HslHAMOnawitr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CR3HslHAMOnawitr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CR3HslHAMOnawitr .error-icon{fill:#552222;}#mermaid-svg-CR3HslHAMOnawitr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CR3HslHAMOnawitr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CR3HslHAMOnawitr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CR3HslHAMOnawitr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CR3HslHAMOnawitr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CR3HslHAMOnawitr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CR3HslHAMOnawitr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CR3HslHAMOnawitr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CR3HslHAMOnawitr .marker.cross{stroke:#333333;}#mermaid-svg-CR3HslHAMOnawitr svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CR3HslHAMOnawitr p{margin:0;}#mermaid-svg-CR3HslHAMOnawitr .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CR3HslHAMOnawitr .cluster-label text{fill:#333;}#mermaid-svg-CR3HslHAMOnawitr .cluster-label span{color:#333;}#mermaid-svg-CR3HslHAMOnawitr .cluster-label span p{background-color:transparent;}#mermaid-svg-CR3HslHAMOnawitr .label text,#mermaid-svg-CR3HslHAMOnawitr span{fill:#333;color:#333;}#mermaid-svg-CR3HslHAMOnawitr .node rect,#mermaid-svg-CR3HslHAMOnawitr .node circle,#mermaid-svg-CR3HslHAMOnawitr .node ellipse,#mermaid-svg-CR3HslHAMOnawitr .node polygon,#mermaid-svg-CR3HslHAMOnawitr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CR3HslHAMOnawitr .rough-node .label text,#mermaid-svg-CR3HslHAMOnawitr .node .label text,#mermaid-svg-CR3HslHAMOnawitr .image-shape .label,#mermaid-svg-CR3HslHAMOnawitr .icon-shape .label{text-anchor:middle;}#mermaid-svg-CR3HslHAMOnawitr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CR3HslHAMOnawitr .rough-node .label,#mermaid-svg-CR3HslHAMOnawitr .node .label,#mermaid-svg-CR3HslHAMOnawitr .image-shape .label,#mermaid-svg-CR3HslHAMOnawitr .icon-shape .label{text-align:center;}#mermaid-svg-CR3HslHAMOnawitr .node.clickable{cursor:pointer;}#mermaid-svg-CR3HslHAMOnawitr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CR3HslHAMOnawitr .arrowheadPath{fill:#333333;}#mermaid-svg-CR3HslHAMOnawitr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CR3HslHAMOnawitr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CR3HslHAMOnawitr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CR3HslHAMOnawitr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CR3HslHAMOnawitr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CR3HslHAMOnawitr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CR3HslHAMOnawitr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CR3HslHAMOnawitr .cluster text{fill:#333;}#mermaid-svg-CR3HslHAMOnawitr .cluster span{color:#333;}#mermaid-svg-CR3HslHAMOnawitr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CR3HslHAMOnawitr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CR3HslHAMOnawitr rect.text{fill:none;stroke-width:0;}#mermaid-svg-CR3HslHAMOnawitr .icon-shape,#mermaid-svg-CR3HslHAMOnawitr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CR3HslHAMOnawitr .icon-shape p,#mermaid-svg-CR3HslHAMOnawitr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CR3HslHAMOnawitr .icon-shape .label rect,#mermaid-svg-CR3HslHAMOnawitr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CR3HslHAMOnawitr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CR3HslHAMOnawitr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CR3HslHAMOnawitr :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    常量

    声明: final int MAX = 100;

    修改: MAX = 200; ✗

    不可修改

    变量

    声明: int count = 10;

    修改: count = 20; ✓

    修改: count = 30; ✓


    八、final关键字详解

    8.1 final可以修饰什么

    final是Java中一个功能丰富的关键字,可以修饰多种程序元素:

    修饰对象含义示例
    变量 值不可修改(常量) final int MAX = 100;
    方法 方法不能被子类重写 public final void method() {}
    类 类不能被继承 public final class String {}
    参数 参数值在方法内不可修改 public void method(final int x) {}

    本章聚焦于final修饰变量的用法。

    8.2 final修饰局部变量

    public void processData() {
    final int threshold = 50; // 局部常量

    if (threshold > 30) {
    final String message = "超过阈值"; // 块内的局部常量
    System.out.println(message);
    // message = "新消息"; // 编译错误:不能修改
    }

    // threshold = 60; // 编译错误:不能修改
    }

    8.3 final修饰实例变量

    实例常量有两种初始化方式:

    public class Config {
    // 方式一:声明时直接初始化
    private final String appName = "教务系统";

    // 方式二:在构造器中初始化(空白final)
    private final String version;
    private final int port;

    public Config(String version, int port) {
    this.version = version;
    this.port = port;
    }

    // 编译错误:final实例变量必须在构造器执行完毕前被赋值
    // 不能在普通方法中修改final实例变量
    // public void setVersion(String v) { this.version = v; }
    }

    8.4 final修饰静态变量

    public class AppConstants {
    // 静态常量——推荐:声明时初始化
    public static final String APP_NAME = "学生成绩管理系统";
    public static final int DEFAULT_PAGE_SIZE = 20;
    public static final double TAX_RATE = 0.13;

    // 静态常量也可以用在静态初始化块中赋值
    public static final long TIMESTAMP;

    static {
    TIMESTAMP = System.currentTimeMillis();
    }
    }


    九、final变量与final引用

    9.1 基本类型与引用类型的区别

    这是理解final关键字最容易出错的地方。final修饰基本类型变量和修饰引用类型变量,含义有微妙但重要的区别:

    类型final的含义不可变的是什么
    基本类型(int、double等) 数值不可修改 变量中存储的值
    引用类型(String、对象等) 引用地址不可修改 变量中存储的引用(指针)

    9.2 基本类型常量

    final int NUMBER = 100;
    // NUMBER = 200; // 编译错误:不能修改值

    基本类型的常量非常简单——值不可改变。

    9.3 引用类型常量

    final StringBuilder builder = new StringBuilder("Hello");
    // builder = new StringBuilder("World"); // 编译错误:不能修改引用

    builder.append(" World"); // 合法!修改对象内容,不是修改引用
    builder.append(" Java"); // 合法!
    System.out.println(builder); // 输出:Hello World Java

    #mermaid-svg-DPUBWN2SNFZem43a{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DPUBWN2SNFZem43a .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DPUBWN2SNFZem43a .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DPUBWN2SNFZem43a .error-icon{fill:#552222;}#mermaid-svg-DPUBWN2SNFZem43a .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DPUBWN2SNFZem43a .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DPUBWN2SNFZem43a .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DPUBWN2SNFZem43a .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DPUBWN2SNFZem43a .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DPUBWN2SNFZem43a .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DPUBWN2SNFZem43a .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DPUBWN2SNFZem43a .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DPUBWN2SNFZem43a .marker.cross{stroke:#333333;}#mermaid-svg-DPUBWN2SNFZem43a svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DPUBWN2SNFZem43a p{margin:0;}#mermaid-svg-DPUBWN2SNFZem43a .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-DPUBWN2SNFZem43a .cluster-label text{fill:#333;}#mermaid-svg-DPUBWN2SNFZem43a .cluster-label span{color:#333;}#mermaid-svg-DPUBWN2SNFZem43a .cluster-label span p{background-color:transparent;}#mermaid-svg-DPUBWN2SNFZem43a .label text,#mermaid-svg-DPUBWN2SNFZem43a span{fill:#333;color:#333;}#mermaid-svg-DPUBWN2SNFZem43a .node rect,#mermaid-svg-DPUBWN2SNFZem43a .node circle,#mermaid-svg-DPUBWN2SNFZem43a .node ellipse,#mermaid-svg-DPUBWN2SNFZem43a .node polygon,#mermaid-svg-DPUBWN2SNFZem43a .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DPUBWN2SNFZem43a .rough-node .label text,#mermaid-svg-DPUBWN2SNFZem43a .node .label text,#mermaid-svg-DPUBWN2SNFZem43a .image-shape .label,#mermaid-svg-DPUBWN2SNFZem43a .icon-shape .label{text-anchor:middle;}#mermaid-svg-DPUBWN2SNFZem43a .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DPUBWN2SNFZem43a .rough-node .label,#mermaid-svg-DPUBWN2SNFZem43a .node .label,#mermaid-svg-DPUBWN2SNFZem43a .image-shape .label,#mermaid-svg-DPUBWN2SNFZem43a .icon-shape .label{text-align:center;}#mermaid-svg-DPUBWN2SNFZem43a .node.clickable{cursor:pointer;}#mermaid-svg-DPUBWN2SNFZem43a .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DPUBWN2SNFZem43a .arrowheadPath{fill:#333333;}#mermaid-svg-DPUBWN2SNFZem43a .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DPUBWN2SNFZem43a .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DPUBWN2SNFZem43a .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DPUBWN2SNFZem43a .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DPUBWN2SNFZem43a .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DPUBWN2SNFZem43a .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DPUBWN2SNFZem43a .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DPUBWN2SNFZem43a .cluster text{fill:#333;}#mermaid-svg-DPUBWN2SNFZem43a .cluster span{color:#333;}#mermaid-svg-DPUBWN2SNFZem43a div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DPUBWN2SNFZem43a .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DPUBWN2SNFZem43a rect.text{fill:none;stroke-width:0;}#mermaid-svg-DPUBWN2SNFZem43a .icon-shape,#mermaid-svg-DPUBWN2SNFZem43a .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DPUBWN2SNFZem43a .icon-shape p,#mermaid-svg-DPUBWN2SNFZem43a .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DPUBWN2SNFZem43a .icon-shape .label rect,#mermaid-svg-DPUBWN2SNFZem43a .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DPUBWN2SNFZem43a .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DPUBWN2SNFZem43a .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DPUBWN2SNFZem43a :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    final StringBuilder builder

    固定指向

    append

    不能指向

    builder 引用不可修改

    StringBuilder对象内容可以修改

    Hello World Java

    新的StringBuilder对象

    核心理解:final锁定的是引用(箭头),而不是被引用的对象本身。

    9.4 经典案例:final数组

    final int[] scores = {85, 90, 78, 92};

    // scores = new int[]{70, 80, 90}; // 编译错误:不能修改引用

    // 但是可以修改数组元素!
    scores[0] = 88; // 合法
    scores[1] = 95; // 合法

    System.out.println(Arrays.toString(scores)); // [88, 95, 78, 92]

    9.5 String的特殊性:不可变对象

    String是Java中的不可变类(Immutable Class),即String对象一旦创建,其内容就不可修改。因此当final和String组合时:

    final String text = "Hello";
    // text = "World"; // 编译错误:不能修改引用

    // String没有修改内容的方法
    // text.??? // 所有String方法都返回新String,不修改原对象

    // 所以 final String 实现了彻底的不可变——引用和内容都不能修改


    十、静态常量:static final组合

    10.1 为什么需要static final

    static final组合定义的常量是Java中最经典的常量形式。static确保常量属于类而不是对象(全局唯一),final确保值不可修改。

    public class MathConstants {
    // 静态常量——属于类的全局常量
    public static final double PI = 3.141592653589793;
    public static final double E = 2.718281828459045;

    // 仅static(类变量,可修改)
    public static double tolerance = 0.0001;

    // 仅final(实例常量,每个对象一份)
    public final double value;

    public MathConstants(double value) {
    this.value = value;
    }
    }

    10.2 static final的使用场景

    // 场景一:数学常量
    public static final double PI = 3.141592653589793;

    // 场景二:配置参数
    public static final int MAX_RETRY_TIMES = 3;
    public static final long CACHE_EXPIRE_SECONDS = 3600;

    // 场景三:状态码
    public static final int STATUS_SUCCESS = 200;
    public static final int STATUS_NOT_FOUND = 404;
    public static final int STATUS_ERROR = 500;

    // 场景四:错误消息
    public static final String ERROR_INVALID_INPUT = "输入参数无效";
    public static final String ERROR_DB_CONNECTION = "数据库连接失败";

    // 场景五:枚举替代值
    public static final int ROLE_ADMIN = 1;
    public static final int ROLE_USER = 2;
    public static final int ROLE_GUEST = 3;

    10.3 常量定义的最佳实践

    在实际项目中,通常将所有常量集中管理:

    /**
    * 系统常量定义类
    */

    public final class SystemConstants {
    // 私有构造器,防止实例化
    private SystemConstants() {
    throw new UnsupportedOperationException("常量类不允许实例化");
    }

    // ========== 应用信息 ==========
    public static final String APP_NAME = "学生成绩管理系统";
    public static final String APP_VERSION = "3.2.1";

    // ========== 分页配置 ==========
    public static final int DEFAULT_PAGE_SIZE = 20;
    public static final int MAX_PAGE_SIZE = 100;

    // ========== 文件上传限制 ==========
    public static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
    public static final String[] ALLOWED_EXTENSIONS = {".pdf", ".doc", ".docx"};

    // ========== 业务状态码 ==========
    public static final int CODE_SUCCESS = 200;
    public static final int CODE_BAD_REQUEST = 400;
    public static final int CODE_UNAUTHORIZED = 401;
    public static final int CODE_SERVER_ERROR = 500;
    }


    十一、为何使用常量

    11.1 消灭魔术数字(Magic Numbers)

    魔术数字是指直接出现在代码中的、没有明确含义的数值。它们让代码难以理解和维护。

    // ❌ 充满魔术数字的代码——难以阅读和维护
    public double calculateArea(double radius) {
    return 3.1415926535 * radius * radius;
    }

    public void setUserStatus(int status) {
    if (status == 1) {
    // 激活用户
    } else if (status == 2) {
    // 冻结用户
    } else if (status == 3) {
    // 删除用户
    }
    }

    // ✅ 使用常量——清晰、可维护
    public static final double PI = 3.1415926535;
    public static final int STATUS_ACTIVE = 1;
    public static final int STATUS_FROZEN = 2;
    public static final int STATUS_DELETED = 3;

    public double calculateArea(double radius) {
    return PI * radius * radius;
    }

    public void setUserStatus(int status) {
    if (status == STATUS_ACTIVE) {
    // 激活用户
    } else if (status == STATUS_FROZEN) {
    // 冻结用户
    } else if (status == STATUS_DELETED) {
    // 删除用户
    }
    }

    11.2 集中化配置管理

    将常量集中定义,修改时只需要改一处,系统其余部分自动生效:

    // 分散的硬编码
    public class ServiceA {
    public void connect() {
    int timeout = 5000; // 超时时间
    // …
    }
    }
    public class ServiceB {
    public void connect() {
    int timeout = 5000; // 另一个服务也写了5000
    // …
    }
    }
    // 如果要改为3000,需要到处修改,容易遗漏

    // 集中管理
    public class AppConfig {
    public static final int CONNECTION_TIMEOUT = 5000;
    public static final String DB_URL = "jdbc:mysql://localhost:3306/edu";
    public static final String DB_USER = "admin";
    public static final String DB_PASSWORD = "secure123";
    }

    public class ServiceA {
    public void connect() {
    int timeout = AppConfig.CONNECTION_TIMEOUT;
    // …
    }
    }
    public class ServiceB {
    public void connect() {
    int timeout = AppConfig.CONNECTION_TIMEOUT;
    // …
    }
    }

    11.3 增强代码可读性

    使用有意义的常量名代替数值,让代码意图一目了然:

    // ❌ 含义不明确
    if (user.getAge() >= 18) { ... }
    if (order.getAmount() > 999) { ... }
    if (attemptCount <= 3) { ... }

    // ✅ 含义明确
    public static final int LEGAL_ADULT_AGE = 18;
    public static final double FREE_SHIPPING_THRESHOLD = 999.0;
    public static final int MAX_LOGIN_ATTEMPTS = 3;

    if (user.getAge() >= LEGAL_ADULT_AGE) { ... }
    if (order.getAmount() > FREE_SHIPPING_THRESHOLD) { ... }
    if (attemptCount <= MAX_LOGIN_ATTEMPTS) { ... }

    11.4 降低出错概率

    // ❌ 容易写错
    if (dayOfWeek == 7) { ... } // 7是周日还是周六?
    if (month == 12) { ... } // 12是12月,容易理解

    // ✅ 不容易写错
    public static final int SUNDAY = 7;
    public static final int DECEMBER = 12;

    if (dayOfWeek == SUNDAY) { ... }


    十二、编译时常量

    12.1 什么是编译时常量

    编译时常量(Compile-Time Constant)是指值在编译阶段就能确定的常量。Java编译器会对编译时常量进行内联优化——在编译时将常量值直接替换到引用处,而不是在运行时查找。

    一个变量要成为编译时常量,必须同时满足:

  • 使用static final修饰
  • 类型是基本类型或String
  • 在声明时直接初始化(不是通过构造器或静态块)
  • 初始值必须是常量表达式(能在编译期求值的表达式)
  • // 这些都是编译时常量
    public static final int MAX = 100;
    public static final String NAME = "Java";
    public static final double RATE = 0.05;
    public static final int CALCULATED = 60 * 60 * 24; // 常量表达式

    // 这些不是编译时常量
    public static final long CURRENT_TIME = System.currentTimeMillis(); // 运行时确定
    public static final int RANDOM = new Random().nextInt(); // 运行时确定
    public static final String INPUT = new Scanner(System.in).nextLine();// 运行时确定

    12.2 内联优化的效果

    // 类A中定义常量
    public class A {
    public static final int VALUE = 100;
    }

    // 类B中使用常量
    public class B {
    public void test() {
    int x = A.VALUE; // 编译后实际变为:int x = 100;
    System.out.println(x);
    }
    }

    内联优化的一个重要后果:如果修改了A类中VALUE的值后只重新编译A类而不编译B类,B类中使用的仍然是旧值。因此,如果常量值可能变化,应考虑改用非编译时常量(如使用方法返回值)。

    12.3 switch-case中的编译时常量

    switch语句的case标签必须是编译时常量:

    public static final int STATUS_ACTIVE = 1;
    public static final int STATUS_INACTIVE = 2;
    public static final int STATUS_DELETED = 3;

    public void handleStatus(int status) {
    switch (status) {
    case STATUS_ACTIVE: // ✓ 编译时常量
    activateUser();
    break;
    case STATUS_INACTIVE: // ✓ 编译时常量
    deactivateUser();
    break;
    case STATUS_DELETED: // ✓ 编译时常量
    deleteUser();
    break;
    }
    }


    十三、空白final变量

    13.1 什么是空白final

    空白final变量(Blank Final Variable)是指在声明时没有赋予初始值的final变量。它必须在每个构造器中被赋值,且只能赋值一次。

    public class Document {
    private final String id; // 空白final
    private final String title; // 空白final
    private final long createdAt; // 空白final

    public Document(String id, String title) {
    this.id = id; // 在构造器中初始化
    this.title = title;
    this.createdAt = System.currentTimeMillis();

    // this.id = "newId"; // 编译错误:final变量只能赋值一次
    }

    // 如果有多个构造器,每个都必须初始化所有空白final变量
    public Document(String title) {
    this.id = UUID.randomUUID().toString(); // 自动生成ID
    this.title = title;
    this.createdAt = System.currentTimeMillis();
    }

    // 编译错误:如果某个构造器遗漏了空白final的初始化
    // public Document() {
    // // 缺少 id、title、createdAt 的初始化
    // }
    }

    13.2 空白final的应用场景

    空白final特别适合**不可变对象(Immutable Object)**的设计模式:

    /**
    * 不可变用户对象——所有属性一旦在构造时确定,就永远不变
    */

    public class ImmutableUser {
    private final String username;
    private final String email;
    private final int age;
    private final LocalDate registrationDate;

    public ImmutableUser(String username, String email, int age) {
    // 参数校验
    if (username == null || username.isEmpty()) {
    throw new IllegalArgumentException("用户名不能为空");
    }
    if (age < 0 || age > 150) {
    throw new IllegalArgumentException("年龄不合法");
    }

    // 防御性复制
    this.username = username;
    this.email = email;
    this.age = age;
    this.registrationDate = LocalDate.now();
    }

    // 只提供getter,不提供setter
    public String getUsername() { return username; }
    public String getEmail() { return email; }
    public int getAge() { return age; }
    public LocalDate getRegistrationDate() { return registrationDate; }
    }

    13.3 空白final与静态final

    静态的空白final变量必须在静态初始化块中赋值:

    public class AppConfig {
    // 静态空白final——在静态初始化块中赋值
    public static final String CONFIG_PATH;
    public static final int MAX_CONNECTIONS;
    public static final boolean DEBUG_MODE;

    static {
    // 可以读取配置文件、计算复杂逻辑来确定常量值
    Properties props = loadProperties();
    CONFIG_PATH = props.getProperty("config.path", "/etc/app/config");
    MAX_CONNECTIONS = Integer.parseInt(
    props.getProperty("max.connections", "100"));
    DEBUG_MODE = Boolean.parseBoolean(
    props.getProperty("debug.mode", "false"));
    }

    private static Properties loadProperties() {
    // 加载配置文件的逻辑
    return new Properties();
    }
    }


    十四、var类型推断(Java 10+)

    14.1 var关键字简介

    Java 10引入了局部变量类型推断(Local-Variable Type Inference),允许使用var关键字声明局部变量而无需显式指定类型。编译器会根据赋值表达式的右侧自动推断变量的类型。

    // 传统写法
    String name = "张三";
    int age = 25;
    List<String> names = new ArrayList<>();

    // 使用var(Java 10+)
    var name = "张三"; // 推断为String
    var age = 25; // 推断为int
    var names = new ArrayList<String>(); // 推断为ArrayList<String>

    14.2 var vs final var

    var可以与final组合使用,声明不可修改的局部变量:

    // 不可修改的局部变量——类型由编译器推断
    final var PI = 3.14159; // 推断为double
    final var MAX_SIZE = 1000; // 推断为int
    final var appName = "管理系统"; // 推断为String

    // PI = 3.14; // 编译错误:final变量不能修改

    14.3 var的使用限制

    var虽然方便,但有严格的使用限制:

    限制说明示例
    只能用于局部变量 不能用于字段、方法参数、返回类型 var name;(类字段)❌
    必须初始化 编译器需要初始值来推断类型 var x; ❌
    不能初始化为null 编译器无法推断null的类型 var x = null; ❌
    不能用于复合声明 一行声明多个变量不能用var var a = 1, b = 2; ❌
    Lambda表达式 不能用于Lambda表达式参数(Java 11+允许) –

    // var的正确使用场景
    var user = new User("张三", 25); // 对象创建
    var list = List.of("A", "B", "C"); // 集合
    var input = new FileInputStream("a.txt"); // IO流
    var result = computeSomething(); // 方法返回值

    // var的不恰当使用——降低可读性
    var x = compute(); // x是什么类型?不清晰
    // 此时应该使用显式类型声明
    ResultType x = compute(); // 清晰明了

    14.4 var使用建议

    // ✅ 推荐使用var的场景
    // 场景1:类型名很长,右侧已经明确了类型
    var userMap = new HashMap<Integer, User>();

    // 场景2:try-with-resources
    try (var reader = new BufferedReader(new FileReader("data.txt"))) {
    // …
    }

    // 场景3:不可实例化的类型
    var list = Collections.emptyList();

    // ❌ 不推荐使用var的场景
    // 场景1:右侧信息不足以推断类型
    var data = service.getData(); // 返回类型不清楚

    // 场景2:基本类型,显式声明更清晰
    // var count = 0; 不如
    int count = 0;


    十五、变量初始化最佳实践

    15.1 总是初始化局部变量

    // ❌ 坏习惯:延迟初始化
    int result;
    if (condition) {
    result = calculateA();
    } else {
    result = calculateB();
    }
    // 容易忘记else分支导致编译错误

    // ✅ 好习惯:声明时初始化或使用三元表达式
    int result = condition ? calculateA() : calculateB();

    // 或者立即赋予默认值
    int result = 0;
    if (condition) {
    result = calculateA();
    } else {
    result = calculateB();
    }

    15.2 使用final优先

    对于不应该被修改的变量,应该立即标注为final:

    // ❌ 让读者自己去判断这个变量是否会被修改
    String databaseUrl = config.getProperty("db.url");
    int maxAttempts = Integer.parseInt(config.getProperty("max.attempts"));

    // ✅ 明确表达意图:这些值在初始化后不会改变
    final String databaseUrl = config.getProperty("db.url");
    final int maxAttempts = Integer.parseInt(config.getProperty("max.attempts"));

    15.3 选择合适的作用域

    // ❌ 作用域过大
    public void processOrders(List<Order> orders) {
    double totalPrice = 0; // 整个方法都能访问
    int orderCount = orders.size(); // 整个方法都能访问
    String report = ""; // 整个方法都能访问

    for (Order order : orders) {
    totalPrice += order.getPrice();
    }

    // 100行之后才使用report
    report = buildReport(totalPrice, orderCount);
    }

    // ✅ 作用域最小化
    public void processOrders(List<Order> orders) {
    int orderCount = orders.size();

    double totalPrice = 0;
    for (Order order : orders) {
    totalPrice += order.getPrice();
    }

    String report = buildReport(totalPrice, orderCount);
    // report只在需要使用时才声明
    }

    15.4 一行一个变量

    // ❌ 一行多个变量——难以阅读和调试
    int a = 1, b = 2, c = 3;
    String x = "hello", y = "world";

    // ✅ 每行一个变量——清晰明了
    int a = 1;
    int b = 2;
    int c = 3;
    String x = "hello";
    String y = "world";

    15.5 变量声明顺序

    在类中,建议按以下顺序声明变量:

    public class OrderService {
    // 1. 静态常量
    public static final int MAX_ITEMS = 100;
    public static final String SERVICE_NAME = "OrderService";

    // 2. 静态变量
    private static int activeOrderCount = 0;
    private static Logger logger = LoggerFactory.getLogger(OrderService.class);

    // 3. 实例常量
    private final String orderId;
    private final LocalDateTime createdAt;

    // 4. 实例变量
    private List<OrderItem> items;
    private OrderStatus status;
    private double totalAmount;

    // 5. 构造器…
    // 6. 方法…
    }


    十六、综合案例:学生成绩管理系统

    下面通过一个综合案例,将本章所学知识点融会贯通:

    import java.time.LocalDateTime;
    import java.util.ArrayList;
    import java.util.List;

    /**
    * 常量定义类
    */

    public final class GradeConstants {
    private GradeConstants() {}

    // 编译时常量
    public static final double PASS_SCORE = 60.0;
    public static final double FULL_SCORE = 100.0;
    public static final int MAX_COURSE_COUNT = 10;

    // 等级常量
    public static final String GRADE_A = "优秀";
    public static final String GRADE_B = "良好";
    public static final String GRADE_C = "中等";
    public static final String GRADE_D = "及格";
    public static final String GRADE_F = "不及格";
    }

    /**
    * 学生成绩——不可变对象设计
    */

    public class StudentGrade {
    // 实例常量(空白final)
    private final String studentId; // 学号
    private final String courseName; // 课程名
    private final double score; // 分数
    private final String grade; // 等级
    private final LocalDateTime recordTime; // 录入时间

    public StudentGrade(String studentId, String courseName, double score) {
    // 参数校验
    if (studentId == null || studentId.isBlank()) {
    throw new IllegalArgumentException("学号不能为空");
    }
    if (score < 0 || score > GradeConstants.FULL_SCORE) {
    throw new IllegalArgumentException("分数必须在0-100之间");
    }

    this.studentId = studentId;
    this.courseName = courseName;
    this.score = score;
    this.grade = calculateGrade(score); // 根据分数计算等级
    this.recordTime = LocalDateTime.now();
    }

    private String calculateGrade(double score) {
    if (score >= 90) return GradeConstants.GRADE_A;
    if (score >= 80) return GradeConstants.GRADE_B;
    if (score >= 70) return GradeConstants.GRADE_C;
    if (score >= GradeConstants.PASS_SCORE) return GradeConstants.GRADE_D;
    return GradeConstants.GRADE_F;
    }

    // 只提供getter方法,不提供setter
    public String getStudentId() { return studentId; }
    public String getCourseName() { return courseName; }
    public double getScore() { return score; }
    public String getGrade() { return grade; }
    public LocalDateTime getRecordTime() { return recordTime; }

    /**
    * 判断是否及格
    */

    public boolean isPassed() {
    return score >= GradeConstants.PASS_SCORE;
    }
    }

    /**
    * 成绩管理服务
    */

    public class GradeService {
    // 静态变量——统计所有实例
    private static int totalRecordsProcessed = 0;

    // 实例变量
    private final List<StudentGrade> grades = new ArrayList<>();
    private String className;

    public GradeService(String className) {
    this.className = className;
    }

    public void addGrade(StudentGrade grade) {
    // 局部变量——仅在方法内使用
    final int beforeSize = grades.size(); // final局部变量

    grades.add(grade);
    totalRecordsProcessed++;

    if (grades.size() > beforeSize) {
    System.out.println("成绩添加成功");
    }
    }

    public double calculateAverage() {
    // 使用var进行类型推断(Java 10+)
    var totalScore = 0.0; // 编译时已确定类型为double

    for (var grade : grades) { // 增强for循环中的var
    totalScore += grade.getScore();
    }

    // 作用域最小化——在需要时才声明变量
    var averageScore = grades.isEmpty() ? 0.0 : totalScore / grades.size();

    return averageScore;
    }

    public static int getTotalRecordsProcessed() {
    return totalRecordsProcessed;
    }
    }

    #mermaid-svg-6tjgUHe3EcC6Y8kd{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6tjgUHe3EcC6Y8kd .error-icon{fill:#552222;}#mermaid-svg-6tjgUHe3EcC6Y8kd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6tjgUHe3EcC6Y8kd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6tjgUHe3EcC6Y8kd .marker.cross{stroke:#333333;}#mermaid-svg-6tjgUHe3EcC6Y8kd svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6tjgUHe3EcC6Y8kd p{margin:0;}#mermaid-svg-6tjgUHe3EcC6Y8kd g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-6tjgUHe3EcC6Y8kd g.classGroup text .title{font-weight:bolder;}#mermaid-svg-6tjgUHe3EcC6Y8kd .cluster-label text{fill:#333;}#mermaid-svg-6tjgUHe3EcC6Y8kd .cluster-label span{color:#333;}#mermaid-svg-6tjgUHe3EcC6Y8kd .cluster-label span p{background-color:transparent;}#mermaid-svg-6tjgUHe3EcC6Y8kd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6tjgUHe3EcC6Y8kd .cluster text{fill:#333;}#mermaid-svg-6tjgUHe3EcC6Y8kd .cluster span{color:#333;}#mermaid-svg-6tjgUHe3EcC6Y8kd .nodeLabel,#mermaid-svg-6tjgUHe3EcC6Y8kd .edgeLabel{color:#131300;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-6tjgUHe3EcC6Y8kd .label text{fill:#131300;}#mermaid-svg-6tjgUHe3EcC6Y8kd .labelBkg{background:#ECECFF;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-6tjgUHe3EcC6Y8kd .classTitle{font-weight:bolder;}#mermaid-svg-6tjgUHe3EcC6Y8kd .node rect,#mermaid-svg-6tjgUHe3EcC6Y8kd .node circle,#mermaid-svg-6tjgUHe3EcC6Y8kd .node ellipse,#mermaid-svg-6tjgUHe3EcC6Y8kd .node polygon,#mermaid-svg-6tjgUHe3EcC6Y8kd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6tjgUHe3EcC6Y8kd .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd g.clickable{cursor:pointer;}#mermaid-svg-6tjgUHe3EcC6Y8kd g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-6tjgUHe3EcC6Y8kd g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-6tjgUHe3EcC6Y8kd .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-6tjgUHe3EcC6Y8kd .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-6tjgUHe3EcC6Y8kd .dashed-line{stroke-dasharray:3;}#mermaid-svg-6tjgUHe3EcC6Y8kd .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-6tjgUHe3EcC6Y8kd #compositionStart,#mermaid-svg-6tjgUHe3EcC6Y8kd .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #compositionEnd,#mermaid-svg-6tjgUHe3EcC6Y8kd .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #dependencyStart,#mermaid-svg-6tjgUHe3EcC6Y8kd .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #dependencyStart,#mermaid-svg-6tjgUHe3EcC6Y8kd .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #extensionStart,#mermaid-svg-6tjgUHe3EcC6Y8kd .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #extensionEnd,#mermaid-svg-6tjgUHe3EcC6Y8kd .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #aggregationStart,#mermaid-svg-6tjgUHe3EcC6Y8kd .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #aggregationEnd,#mermaid-svg-6tjgUHe3EcC6Y8kd .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #lollipopStart,#mermaid-svg-6tjgUHe3EcC6Y8kd .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd #lollipopEnd,#mermaid-svg-6tjgUHe3EcC6Y8kd .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-6tjgUHe3EcC6Y8kd .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-6tjgUHe3EcC6Y8kd .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6tjgUHe3EcC6Y8kd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6tjgUHe3EcC6Y8kd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6tjgUHe3EcC6Y8kd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    管理

    使用

    使用

    «final class»

    GradeConstants

    +PASS_SCORE: double

    +FULL_SCORE: double

    +MAX_COURSE_COUNT: int

    +GRADE_A~F: String

    «immutable»

    StudentGrade

    -studentId: String

    -courseName: String

    -score: double

    -grade: String

    -recordTime: LocalDateTime

    +isPassed() : : boolean

    GradeService

    -totalRecordsProcessed: int

    -grades: List<StudentGrade>

    -className: String

    +addGrade(StudentGrade) : : void

    +calculateAverage() : : double


    本章关键词回顾

    关键词说明
    变量(Variable) 用于存储数据的一块命名内存空间
    局部变量 在方法或代码块内部声明的变量,存储在栈中,无默认值
    实例变量 在类中声明、无static修饰的变量,属于对象,存储在堆中
    静态变量 用static修饰的变量,属于类,所有实例共享
    作用域(Scope) 变量有效的代码范围,由花括号决定
    变量遮蔽(Shadowing) 内层变量与外层变量同名时,内层变量覆盖外层变量
    生命周期 变量从创建到销毁的整个过程
    垃圾回收(GC) JVM自动回收不再使用的对象内存
    final 声明常量的关键字,表示"一旦赋值,永不改变"
    常量(Constant) 使用final修饰的、值不可修改的变量
    编译时常量 值在编译期可确定的常量,会被内联优化
    空白final 声明时未初始化的final变量,必须在构造器中初始化
    魔术数字 代码中直接出现的、含义不明的数值
    var Java 10引入的局部变量类型推断关键字

    思考与练习

    基础练习

  • 指出以下代码中的错误并改正:
  • public class Test {
    private int count;
    private static String name;

    public void method(int x) {
    int y;
    System.out.println(y); // 错误1

    if (x > 0) {
    int y = 10; // 错误2
    String name = "test";
    }

    final int z;
    z = 100;
    z = 200; // 错误3
    }
    }

  • 分析以下代码的输出结果:
  • public class ScopeTest {
    private static int value = 100;

    public static void main(String[] args) {
    int value = 200;
    System.out.println(value);

    {
    int value = 300;
    System.out.println(value);
    }
    }
    }

    进阶练习

  • 设计一个BankAccount(银行账户)类,要求:

    • 使用final关键字确保账号(accountNumber)在创建后不可修改
    • 使用静态常量定义银行名称和最低余额限制
    • 提供一个withdraw(取款)方法,不允许取款后余额低于最低限制
    • 使用静态变量统计所有账户的总余额
  • 分析以下代码,判断每个final修饰的效果:

  • final List<String> names = new ArrayList<>();
    names.add("张三");
    names.add("李四");
    names = new ArrayList<>(); // 能否编译通过?

  • 编写一个Config类,要求通过构造器从配置文件中读取以下信息作为常量:数据库URL、最大连接数、超时时间。使用空白final实现。
  • 思考题

  • 为什么Java设计了空白final机制?它解决了什么实际问题?

  • String是final类,String对象的内容也不可变。那么final String和普通的String在行为上有区别吗?为什么?


  • 下一篇文章预览

    掌握了变量与常量的基础知识后,下一篇文章我们将深入探讨运算符与表达式——从算术运算到逻辑运算,从运算符优先级到类型转换规则。你将学到如何使用Java丰富的运算符来构建复杂的数据处理逻辑,以及如何避免常见的运算符陷阱。


    本章完 | 变量是数据的基础容器,常量是稳定的数据锚点。理解它们,你就掌握了Java数据管理的核心机制。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 第33章 变量与常量:变量声明、作用域与final关键字
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!