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

8.1 类变量和类方法

8.1 类变量和类方法

8.1.1 类变量-提出问题

在面向对象编程中,我们会遇到这样的场景:多个对象需要共享同一份数据 。比如定义学生类时,想统计所有学生一共缴纳的学费,若用普通的实例变量,每个对象的该变量都是独立的,无法直接实现“所有对象共享数据”的需求,这就引出了类变量(静态变量)来解决这类问题。

8.1.2 传统的方法来解决

若不使用类变量,要实现类似“统计所有学生总学费”的功能,可能需要在类外部定义一个全局变量,然后在操作学生对象(如创建学生、缴纳学费时)去修改这个全局变量 。但这种方式会让代码的耦合性变高,全局变量容易被其他无关代码意外修改,而且从面向对象的封装性角度看,破坏了类的封装,不利于代码的维护和扩展。

8.1.3 类变量快速入门

定义与示例

类变量是用 static 修饰的变量,属于类本身,而非单个对象。以下通过学生类示例展示:

class Student {// 实例变量,每个学生对象独有的姓名String name; // 类变量,所有 Student 对象共享的总学费static double totalFee; public Student(String name) {this.name = name;}
}public class Test {public static void main(String[] args) {// 直接通过类名访问类变量,设置所有学生的总学费Student.totalFee = 10000; Student s1 = new Student("张三");Student s2 = new Student("李四");// 输出总学费,验证共享性System.out.println(Student.totalFee); }
}

在上述代码中,totalFee 是类变量,所有 Student 对象都共享它的值,通过 Student.totalFee 就能直接操作这份共享数据 。

8.1.4 类变量内存布局

存储位置与流程

当类加载时,类的相关信息(包括类变量)会存储在方法区的静态域中 。实例变量则存储在堆内存中,每个对象的实例变量是独立的。以 Student 类为例,totalFee(类变量)在方法区,而每个 Student 对象(如 s1s2)的 name(实例变量)在堆中各自有一份。当通过 Student.totalFee 操作时,直接修改的是方法区里类变量的值,所有对象访问的都是这同一个位置的数据,从而实现共享。

8.1.5 什么是类变量

类变量,也叫静态变量,是被 static 关键字修饰的变量 。它属于整个类,而不是类的某个实例(对象)。对比实例变量(普通属性),实例变量是每个对象单独拥有的属性,各个对象的实例变量相互独立;类变量则是所有对象共享的,一处修改,处处可见。

8.1.6 如何定义类变量

语法格式

类变量的定义语法为:[访问修饰符] static 数据类型 变量名; ,推荐把 static 写在访问修饰符之后,例如 public static double totalFee; ,这样符合编码规范,也更清晰体现其是类变量的特性。访问修饰符(如 publicprivate 等)用于控制类变量的访问权限 。

8.1.7 如何访问类变量

访问方式

  • 推荐方式类名.类变量名 ,比如 Student.totalFee ,这种方式清晰表明是在访问类共享的变量,语义明确 。
  • 不推荐方式对象名.类变量名 ,像 s1.totalFee ,虽然语法上可行,但容易让人误解该变量是对象独有的,混淆类变量和实例变量的区别 。
  • 前提条件:要满足访问修饰符的权限,若类变量用 private 修饰,外部类一般无法直接通过上述方式访问,需要借助类的 getter 等方法间接访问 。

8.1.8 类变量使用注意事项和细节讨论

  1. 类加载时初始化:类变量在类加载阶段就完成初始化,不用创建对象就能使用。比如还没创建 Student 对象时,就可以通过 Student.totalFee 获取或设置它的值 。
  2. 与实例变量访问区别:实例变量不能通过 类名.变量名 方式访问,因为实例变量属于对象,必须先创建对象才能访问,而类变量属于类,不依赖对象存在 。
  3. 生命周期:类变量随着类的加载而创建,随着类的卸载而销毁,其生命周期贯穿类存在的整个过程,比对象的生命周期更长 。

8.1.12 类方法经典的使用场景

典型场景与示例

  • 工具类:像 Math 类的数学计算方法(如 Math.abs() )、Arrays 类的数组操作方法(如 Arrays.sort() ),这些方法不依赖特定对象,属于通用工具逻辑,设计成类方法(静态方法),无需创建对象就能调用,方便快捷 。
  • 通用逻辑实现:比如实现打印一维数组的功能,写成类方法后,任何地方要打印数组,直接用 工具类名.打印方法名 即可,不用每次创建工具类对象,提升开发效率,示例如下:
class ArrayUtils {public static void printArray(int[] arr) {for (int num : arr) {System.out.print(num + " ");}System.out.println();}
}public class Test {public static void main(String[] args) {int[] arr = {1, 2, 3};// 直接通过类名调用类方法ArrayUtils.printArray(arr); }
}

8.1.13 类方法使用注意事项和细节讨论

  1. 加载与 this 参数:类方法和普通方法都在类加载时加载到方法区存储结构信息,但类方法中没有 this 参数(因为不属于具体对象),普通方法隐含 this 参数(代表当前调用的对象) 。
  2. 调用方式:类方法可以通过 类名.类方法名对象名.类方法名 调用(推荐前者);普通方法必须通过 对象名.方法名 调用,因为依赖对象的状态 。
  3. 关键字限制:类方法中不允许使用 thissuper 关键字,因为类方法不关联具体对象,不存在 this 指向的当前对象,也用不到 super 相关的继承上下文;而普通方法(成员方法)可以使用这些关键字 。
  4. 成员访问限制:类方法(静态方法)中只能访问静态变量或静态方法,因为非静态成员属于对象,类方法执行时可能没有对象存在;普通成员方法既可以访问非静态成员,也能访问静态成员(只要符合访问权限) 。
http://www.sczhlp.com/news/8567/

相关文章:

  • 第二十八天(补8.3)
  • Java程序运行机制
  • 涨价
  • 2.6多个函数(一个文件中包含两个函数)
  • Java的HelloWorld
  • 【优选算法】BFS解决拓扑排序 - 详解
  • 使用Rust操作Windows ACL:windows-acl库简介
  • ANR问题产生原理和分析思路总结
  • Markdown语法的用法
  • 第二十六篇
  • JDK的安装与卸载
  • 视频分割技术:方法、挑战与应用
  • 软工8.9
  • 《触龙说赵太后》
  • 第二十七天(补8.2)
  • P13680 [IAMOI R2] 未送出的花 做题记录
  • Debian 12(Bookworm)apt 包管理器 国内源配置
  • JDK、JRE和JVM
  • 8.9
  • 8-9
  • 可以赚钱的小游戏
  • 同时求最值(min 和 max)时如何把比较次数压到最少
  • 1.C++基础
  • uclamp 的桶化算法是什么?
  • 数论函数
  • 8月9号
  • 8月9日随笔
  • CF1404C Fixed Point Removal
  • 竞赛日记
  • 基本的DOS命令