【Java 每日一练 - Day5】static 关键字全解析!静态方法 / 变量 / 代码块 + 面试避坑指南
哈喽,刷题小伙伴们!Day4 关于异常体系的 finally 坑点是不是让你印象深刻?今天咱们攻克 Java 基础中极具实用性的考点 ——static 关键字,这题不仅考用法,还常结合类加载机制、对象实例化流程出题,是面试高频加分项,赶紧往下看!
今日题目
1.static 关键字的核心作用是什么?可修饰哪些元素?
2.static 方法为什么不能调用非 static 成员(变量 / 方法)?
3.静态代码块、构造代码块、构造方法的执行顺序是什么?
一、基础答案
1.static 关键字的核心作用
- 核心:属于类,不属于单个对象,实现 “资源共享”(静态成员被该类所有对象共用);
- 可修饰元素:
- 静态变量(类变量):类加载时初始化,存储在方法区,全局唯一;
- 静态方法(类方法):无需创建对象,直接通过 “类名。方法名” 调用;
- 静态代码块:类加载时执行,用于初始化静态变量或执行预处理操作;
- 静态内部类:独立于外部类对象,无需依赖外部类实例即可创建。
2.static 方法不能调用非 static 成员的原因
- 加载顺序:静态成员(方法 / 变量)在类加载时初始化,非 static 成员(实例变量 / 方法)在对象创建时初始化;
- 依赖关系:static 方法执行时,可能还未创建任何对象,而非 static 成员必须依附于具体对象存在,因此无法直接调用;
- 反例:非 static 方法可以调用 static 成员(因为类加载一定早于对象创建)。
3.核心执行顺序(面试高频)
当创建对象时,执行顺序为:
静态代码块 → 构造代码块 → 构造方法
- 静态代码块:只执行一次(类加载时),多个静态代码块按定义顺序执行;
- 构造代码块:每次创建对象都执行,多个构造代码块按定义顺序执行;
- 构造方法:每次创建对象执行,根据创建对象时的参数匹配对应构造方法。
二、深度拆解(面试加分项)
1. 静态变量 vs 实例变量 底层区别
|
特性 |
静态变量(类变量) |
实例变量 |
|
存储位置 |
方法区(JDK8 后为元空间) |
堆内存(对象所属空间) |
|
初始化时机 |
类加载时(首次使用类时) |
对象创建时(new 关键字触发) |
|
生命周期 |
与类的生命周期一致(JVM 退出时销毁) |
与对象的生命周期一致(GC 回收时销毁) |
|
访问方式 |
类名。变量名(推荐)、对象。变量名 |
只能通过对象。变量名访问 |
|
共享性 |
该类所有对象共用 |
每个对象独立拥有,互不影响 |
class Student {
static String school = "Java编程学院"; // 静态变量(所有学生共用)
String name; // 实例变量(每个学生独立)
public Student(String name) {
this.name = name;
}
}
public class TestStatic {
public static void main(String[] args) {
Student s1 = new Student("张三");
Student s2 = new Student("李四");
System.out.println(s1.school); // 输出:Java编程学院
System.out.println(s2.school); // 输出:Java编程学院
Student.school = "Java面试训练营"; // 通过类名修改静态变量
System.out.println(s1.school); // 输出:Java面试训练营(所有对象共享修改)
System.out.println(s2.name); // 输出:李四(实例变量独立)
}
}
2. 静态代码块的实战应用
静态代码块常用于 “一次性初始化”(如加载配置文件、初始化工具类),示例:
// 工具类:加载数据库配置
class DBUtil {
static String url;
static String username;
static String password;
// 静态代码块:类加载时执行,只执行一次
static {
System.out.println("加载数据库配置...");
url = "jdbc:mysql://localhost:3306/test";
username = "root";
password = "123456";
}
public static void connect() {
System.out.println("连接数据库:" + url);
}
}
public class TestDBUtil {
public static void main(String[] args) {
DBUtil.connect(); // 首次使用类,触发静态代码块执行
DBUtil.connect(); // 再次调用,静态代码块不再执行
}
}
输出结果:
加载数据库配置...
连接数据库:jdbc:mysql://localhost:3306/test
连接数据库:jdbc:mysql://localhost:3306/test
3. 静态内部类的核心特性
- 静态内部类不能访问外部类的非 static 成员(无外部类对象引用);
- 外部类可以访问静态内部类的所有成员(无论访问修饰符);
- 创建方式:外部类名.静态内部类名 实例 = new 外部类名.静态内部类名();(无需创建外部类对象);
- 应用场景:常用于工具类封装(如 HashMap 中的 EntrySet 静态内部类)。
三、面试避坑提醒
1.避免在静态方法中使用 this 或 super 关键字(this 指向当前对象,静态方法无对象关联);2.静态变量线程不安全:多线程环境下修改静态变量,需加锁(如 synchronized)保护;
2.静态代码块不能访问非 static 成员:类加载时实例变量还未初始化,直接访问会编译报错;
3.不要滥用 static:静态成员生命周期长,过度使用可能导致内存泄漏(如静态集合缓存大量对象)。
四、今日打卡
评论区留下你的答案:以下代码的执行顺序和输出结果是什么?✅
class Person {
// 静态代码块1
static {
System.out.println("静态代码块1");
}
// 构造代码块
{
System.out.println("构造代码块");
}
// 构造方法
public Person() {
System.out.println("无参构造方法");
}
// 静态代码块2
static {
System.out.println("静态代码块2");
}
}
public class TestStaticOrder {
public static void main(String[] args) {
new Person();
new Person();
}
}
(提示:结合静态代码块、构造代码块、构造方法的执行顺序分析)
文末预告
Day6 预告:ArrayList 和 LinkedList 的核心区别!底层实现、性能对比、适用场景一次说透,带你吃透 Java 集合框架高频考点~明天继续刷题!
更多推荐


所有评论(0)