static修饰符决定变量属于类而非实例,所有对象共享同一内存空间,随类加载而初始化、卸载而销毁;可见性由private、public等访问修饰符单独控制,二者配合定义访问权限与共享范围。

static 修饰符本身不直接控制“可见性”,它控制的是变量的归属和生命周期;真正的可见性由访问修饰符(如 private、public 等)决定。static 和访问修饰符配合使用,才能完整定义一个类变量能否被外部访问、由谁共享、在何处可用。
static 决定“属于谁”:类级共享,非实例独有
被 static 修饰的变量属于类本身,而不是某个具体对象。所有实例共享同一份内存空间,无论创建多少个对象,该变量只有一份拷贝。
- 通过类名直接访问,例如 ClassName.staticVar,无需实例化对象
- 静态变量在类加载时初始化,随类存在而存在,不依赖对象生命周期
- 适合存放全局配置、计数器、常量缓存等跨实例一致的数据
可见性由访问修饰符单独负责
static 只管“是不是共享”,不管“能不能看到”。能否访问,取决于你加了哪个访问修饰符:
- private static int count; → 仅本类内部可读写,哪怕用类名访问也不行
- protected static String TAG; → 同包类 + 不同包的子类可访问
- public static final String VERSION = "1.0"; → 任意位置可通过 ClassName.VERSION 访问
- 默认(无修饰符)static 变量 → 仅同一包内类可通过类名访问
常见组合与实际影响
不同修饰符搭配 static 会产生明确的行为差异:
立即学习“Java免费学习笔记(深入)”;
- private static 是最推荐的起点:封装数据,防止外部误改,同时保留类级共享能力
- public static final 常用于常量,如 Math.PI 或自定义枚举标识,安全且语义清晰
- 避免 public static 非 final 变量:外部可随意赋值,破坏状态一致性,易引发并发或逻辑错误
- 不要用 protected static 暴露内部状态给子类:子类仍可能绕过校验修改,应优先提供受控的静态方法
注意:static 不改变访问修饰符的作用范围
修饰符的权限规则完全不变——只是作用对象从“实例”变成了“类”:
- private 依然只对本类可见,子类无法继承或访问
- default(包私有)依然只限同包,哪怕加了 static,其他包也看不到
- protected 对子类的可见性,只适用于继承关系中的成员访问,不是“所有子类都能调用 ClassName.protectedStaticVar”


















