编程自学指南:java程序设计开发,static 关键字详解课件(初学者版)
一、课程信息
学习目标
- 理解 static 的四大核心用法(变量 / 方法 / 代码块 / 内部类)
- 掌握静态成员与非静态成员的本质区别
- 能通过 static 实现数据共享、工具类设计等场景
- 避免 static 常见误用(如内存泄漏、非静态访问)
二、课程导入:生活中的静态
🌰 生活案例:班级人数统计
- 每个学生对象有姓名(非静态属性),但班级总人数是所有学生共享的(静态属性)
- 非静态实现:每次创建学生对象时手动累加,易出错
- 静态实现:用 static 变量自动统计,天然共享
三、static 变量:类级别的数据共享
1. 定义与特点
- 语法:
static 数据类型 变量名;
- 特点:属于类,所有对象共享,内存中只有一份
2. 案例:学生人数统计
class Student {
private String name;
static int totalStudents = 0; // 静态变量(类变量)
public Student(String name) {
this.name = name;
totalStudents++; // 每创建一个对象,总人数+1
}
public void showInfo() {
System.out.println(name + ",班级总人数:" + totalStudents);
}
}
public class StaticVarDemo {
public static void main(String[] args) {
Student stu1 = new Student("张三");
Student stu2 = new Student("李四");
stu1.showInfo(); // 输出:张三,班级总人数:2
stu2.showInfo(); // 输出:李四,班级总人数:2
System.out.println(Student.totalStudents); // 直接通过类名访问:2
}
}
3. 内存图解(重点!)
- 非静态变量:每个对象独立存储(堆中)
- 静态变量:存储在方法区(类信息中),所有对象共享
四、static 方法:类级别的工具方法
1. 定义与特点
- 语法:
public static 返回类型 方法名() { ... }
- 特点:
- 无需创建对象,直接通过类名调用
- 只能访问静态成员(非静态成员属于对象,可能不存在)
2. 案例:数学工具类
class MathUtils {
// 静态方法:计算圆面积
public static double circleArea(double radius) {
return Math.PI * radius * radius;
}
// 非静态方法:需要对象才能调用
public double squareArea(double side) {
return side * side;
}
}
public class StaticMethodDemo {
public static void main(String[] args) {
double area = MathUtils.circleArea(5); // 直接调用静态方法
System.out.println("圆面积:" + area);
MathUtils utils = new MathUtils();
double square = utils.squareArea(3); // 非静态方法需对象
}
}
3. 静态方法 vs 非静态方法
特性 | 静态方法 | 非静态方法 |
---|---|---|
调用方式 | 类名。方法 () | 对象。方法 () |
能否访问静态成员 | 能 | 能 |
能否访问非静态成员 | 不能(非静态成员属于对象) | 能 |
五、static 代码块:类加载时的初始化
1. 定义与执行时机
- 语法:
static { // 初始化代码 }
- 执行时机:类第一次被加载时执行,且只执行一次
2. 案例:数据库连接初始化
class Database {
static String url;
static String username;
// 静态代码块:类加载时读取配置
static {
System.out.println("加载数据库配置...");
url = "jdbc:mysql://localhost:3306/test";
username = "root";
}
public static void connect() {
System.out.println("连接到 " + url + ",用户:" + username);
}
}
public class StaticBlockDemo {
public static void main(String[] args) {
Database.connect(); // 第一次调用触发类加载,执行静态代码块
Database.connect(); // 第二次调用不再执行静态代码块
}
}
六、static 内部类:独立于外部类的存在
1. 定义与特点
- 语法:
class Outer { static class Inner { // 静态内部类 // 可以有静态/非静态成员 } }
- 特点:
- 不持有外部类引用(与非静态内部类不同)
- 可以定义静态成员
2. 案例:字典工具类
class Dictionary {
private static final String[] WORDS = {"apple", "banana", "cherry"};
// 静态内部类:提供搜索功能
static class Searcher {
public static boolean contains(String word) {
for (String w : WORDS) {
if (w.equals(word)) return true;
}
return false;
}
}
}
public class StaticInnerClassDemo {
public static void main(String[] args) {
boolean hasApple = Dictionary.Searcher.contains("apple");
System.out.println("包含apple吗?" + hasApple); // true
}
}
七、static 关键字四大应用场景
场景 1:全局数据共享(如计数器)
class Counter {
static int count = 0;
Counter() { count++; }
}
场景 2:工具类设计(如 Collections)
class StringUtils {
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
}
场景 3:单例模式(静态内部类实现)
class Singleton {
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
场景 4:避免重复代码(静态代码块初始化)
static {
System.loadLibrary("awt"); // 加载本地库(如Java图形库)
}
八、初学者必避的 5 大误区
误区 1:在静态方法中访问非静态成员
class Test {
int num;
static void printNum() {
System.out.println(num); // ❌ 编译错误!静态方法不能访问非静态变量
}
}
误区 2:用对象调用静态方法(虽然合法但不推荐)
MathUtils utils = new MathUtils();
utils.circleArea(5); // ✅ 合法,但应使用 MathUtils.circleArea(5)
误区 3:静态变量导致的内存泄漏
class Leak {
static List<Object> list = new ArrayList<>(); // 静态变量生命周期与类相同
void addToStaticList() {
list.add(new Object()); // 若持续调用,内存不断增长
}
}
误区 4:多个类加载导致静态变量重置
// 当类被卸载(极少发生),静态变量会重置(Java Web中可能出现)
误区 5:静态内部类持有外部类引用
class Outer {
static class Inner {
void accessOuter() {
// 无法访问Outer的非静态成员,因为静态内部类不持有外部类引用
}
}
}
九、课堂练习
练习 1:模拟银行账户(静态变量统计总金额)
需求:
- 每个账户有余额(非静态)
- 所有账户总金额用静态变量统计
- 提现时减少余额和总金额
参考代码:
class BankAccount {
private double balance;
static double totalBalance = 0;
public BankAccount(double balance) {
this.balance = balance;
totalBalance += balance;
}
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
totalBalance -= amount;
}
}
}
十、课程总结
知识图谱:
static关键字 → 类级别的成员
↳ 静态变量:所有对象共享,方法区存储
↳ 静态方法:无需对象,只能访问静态成员
↳ 静态代码块:类加载时执行一次
↳ 静态内部类:独立于外部类,无隐式引用
口诀记忆:
“static 是类的,非 static 是对象的,
静态方法无 this,共享数据用静态,
工具类全静态,代码块类加载!”
十一、课后作业(必做 + 选做)
必做 1:设计一个工具类
需求:
- 包含静态方法
reverseString(String str)
,反转字符串 - 包含静态变量
version
记录工具类版本(如 "1.0")
必做 2:统计网站在线人数
需求:
- 每次用户登录时,静态变量
onlineUsers
+1 - 退出时 - 1
- 提供静态方法
getOnlineUsers()
获取在线人数
选做:用静态内部类实现懒汉式单例
提示:利用静态内部类的延迟加载特性