大家好这里是后端基础拾光集。static这个关键字几乎每个 Java 项目里都能看到。 但很多人写到它时只知道 “加了 static 就能直接调用”至于为什么能调用、什么时候该用、什么时候不能用却说不清楚。接下来我们通过用「班级学生」把static一次性搞透彻。一、先建立一个类比模型把class想成一个班级static就是贴在班级公告栏上的东西而不是每个学生自己书包里的东西。类比Java 概念班级公告栏全班共用一份静态变量 / 静态方法每个学生自己的书包人手一份实例变量 /成员变量/ 实例方法开学第一天全班一起布置公告栏静态代码块二、static 变量全班级共用的一份我们可以把类想象成一个班级。 普通成员变量是每个学生自己的作业本每个对象都有一份。 而static变量是贴在教室墙上的班级花名册全班共用一份。class Student { private String name; // 普通成员变量每个学生自己的名字 private static String classRoom; // 静态变量全班共用的教室 }namenew Student()一次就多一份各自独立。school不管 new 多少个学生内存里只有一份所有学生共享。Student a new Student(); a.name 小明; Student b new Student(); b.name 小红; Student.classRoom 二班; // 改一次 System.out.println(a.school); // 二班 System.out.println(b.school); // 二班 —— 大家都变了关键点静态变量属于类不属于对象。只要这个类被加载static 变量就会存在。 任何一个对象修改它其他对象看到的都是修改后的值。 用类名.变量访问才是规范写法。适用场景真正全局共享、与具体对象无关的数据。常量static final double PI 3.14159;计数器统计一共创建了多少个学生配置项、全局缓存一句话记忆普通变量属于对象static 变量属于类。三、static 方法不需要学生本人也能使用的公共饮水机普通成员方法必须先有一个具体对象才能调用就像必须找到某个学生才能看他的作业本。static方法不依赖具体对象可以直接通过类名调用就像教室里的公共饮水机谁都可以用。正因为不依赖对象static 方法里不能直接访问普通成员变量或普通成员方法。 它能访问的主要是 static 成员以及方法参数里传入的数据。class Student { static int count 0; static int getCount() { // 静态方法 return count; } void sayHello() { // 普通成员方法 System.out.println(我是学生); } }调用方式对比Student.getCount(); // 静态方法类名直接调不需要对象 Student s new Student(); s.sayHello(); // 普通成员方法必须先有对象核心规则也是面试常考静态方法里不能直接访问实例变量和实例方法。为什么因为静态方法可以在没有任何对象的情况下被调用而实例变量/方法必须依附于某个对象才存在。你没对象凭什么用别人的书包class Student { String name; static void printName() { System.out.println(name); // ❌ 编译报错name 是哪个学生的 } }反过来实例方法可以访问静态变量/静态方法因为对象一定存在于类之中。适用场景工具类方法与具体对象无关。Math.max()、Arrays.sort()、Integer.parseInt()工厂方法、单例的getInstance()四、static 代码块开学第一天全班一起布置static代码块会在类第一次被加载时执行而且通常只执行一次早于任何对象创建。class Student { static String classRoom; static ListString rules; static { // 静态代码块 classRoom 二班; rules new ArrayList(); rules.add(不准迟到); System.out.println(静态代码块执行了); } }new Student(); new Student(); new Student(); // 输出静态代码块执行了 —— 只打印一次适用场景初始化静态资源且初始化逻辑比较复杂不止一行赋值。加载配置文件初始化静态集合、连接池注册驱动如果只是简单赋值直接static int x 10;就够了不用写代码块。它适合做一些类级别的初始化比如读取配置、初始化静态资源、建立连接池等。 但别把复杂业务逻辑塞进去否则类加载过程会变得很重问题也很难排查。五、AI 最爱踩的坑AI 写工具类时很容易把方法都写成 static。 这对于 “纯工具方法” 来说没问题比如字符串处理、数值计算。 但如果对象本身有状态就不该乱用 static。// ❌ 错误示范把有状态的计数器写成 static class Counter { private static int count 0; public void increment() { count; } }这里的问题是count被所有对象共用。 你创建两个Counter对象各自调用increment()结果会互相影响。 这不是对象自己的状态而是全局状态。// ✅ 正确示范状态属于对象工具行为可以 static class Counter { private int count 0; public void increment() { count; } public static boolean isPositive(int value) { return value 0; } }六、static 最容易混淆的 4 个问题问题 1static 方法里为什么不能直接访问非 static 成员因为非 static 成员属于具体对象而 static 方法调用时可能根本没有对象存在。 没有对象就没法访问对象里的成员。问题 2static 可以修饰类吗只有内部类可以是static。 普通顶级类不能用static修饰。问题 3static 变量一定在方法区吗基础理解阶段可以先记static 变量随着类加载存在被类的所有对象共享。问题 4static 一定线程安全吗不一定。 如果多个线程同时修改同一个 static 变量就会产生线程安全问题。✅ 核心总结普通变量属于对象static 变量属于类被所有对象共享。static 方法不依赖对象可以通过类名直接调用。static 方法不能直接访问非 static 成员。static 代码块在类第一次加载时执行常用于类级初始化。纯工具方法可以 static对象有自己状态时不要乱用 static。记住一句话static 表达的是「属于类、不属于对象」。每次想加 static先问自己这个数据/方法是不是「没有某个具体对象也应该存在」是 → 用不是 → 别用。系列专栏后端基础拾光集本系列避开教科书式八股讲解生活化案例讲解 Java 底层原理覆盖面试、生产开发高频知识点。已更新集合底层源码、红黑树、泛型、Java 异常、Integer 缓存池、equals hashCode、Spring 事务七大陷阱。专栏持续更新 Java 后端基础、源码、面试踩坑干货欢迎关注一起学习。如有疑问欢迎评论区留言讨论。
阅读完成 · 觉得有帮助?