一句话说透Java里面的静态属性与静态方法

202 阅读3分钟

一句话总结:
静态属性和方法就像共享单车,属于整个小区(类),谁(对象)都能用,但骑完记得别乱停(线程安全)!


一、静态属性(Static Fields)——小区公告板

比喻:小区里挂个公告板,所有住户(对象)都能看到并修改,但改的内容会影响所有人。

特点:

  • 属于类:用 static 修饰,不依赖对象实例。
  • 共享数据:所有对象共用同一份数据。
  • 内存分配:类加载时分配内存,程序结束时销毁。

代码示例:

class Student {  
    static String school = "光明小学"; // 静态属性,所有学生共享  
    String name; // 实例属性,每个学生独有  

    Student(String name) {  
        this.name = name;  
    }  
}  

public static void main(String[] args) {  
    Student s1 = new Student("小明");  
    Student s2 = new Student("小红");  

    System.out.println(s1.school); // 输出:光明小学  
    System.out.println(s2.school); // 输出:光明小学  

    Student.school = "希望小学"; // 直接通过类名修改  
    System.out.println(s1.school); // 输出:希望小学(所有人受影响!)  
}  

适用场景:

  • 共享配置(如数据库连接参数)。
  • 全局计数器(统计对象数量)。

坑点:

  • 线程不安全:多个线程同时修改静态属性需加锁(如 synchronized)。
  • 内存泄漏:静态属性长期持有大对象不释放。

二、静态方法(Static Methods)——小区公共电话

比喻:小区门口有个公共电话,不用进谁家(创建对象)就能直接打。

特点:

  • 直接通过类名调用:如 Math.sqrt(9)
  • 不能访问实例成员:只能操作静态属性和其他静态方法。

代码示例:

class MathUtils {  
    static double PI = 3.1415926; // 静态属性  

    // 静态方法:计算圆面积  
    static double calcCircleArea(double radius) {  
        return PI * radius * radius;  
    }  

    // 错误示例:静态方法访问实例属性  
    // void printName() {  
    //     System.out.println(name); // 编译错误!name是非静态的  
    // }  
}  

public static void main(String[] args) {  
    double area = MathUtils.calcCircleArea(2.0); // 直接调用  
    System.out.println(area); // 输出:12.5663704  
}  

适用场景:

  • 工具类方法(如 Arrays.sort())。
  • 工厂方法(如 LocalDate.now())。

坑点:

  • 无法重写:子类定义同名静态方法只是隐藏父类方法,非多态。
  • 滥用导致代码僵化:过度使用静态方法让代码难以扩展和测试。

三、静态代码块(Static Block)——小区物业初始化

比喻:小区交房时,物业统一配置消防设施(只执行一次)。

特点:

  • 类加载时自动执行,用于初始化静态属性。

代码示例:

class DatabaseConfig {  
    static String url;  
    static String username;  

    static {  
        // 模拟读取配置文件  
        url = "jdbc:mysql://localhost:3306/test";  
        username = "admin";  
        System.out.println("数据库配置初始化完成!");  
    }  
}  

public static void main(String[] args) {  
    // 第一次访问类时触发静态代码块  
    System.out.println(DatabaseConfig.url);  
}  
// 输出:  
// 数据库配置初始化完成!  
// jdbc:mysql://localhost:3306/test  

四、静态内部类(Static Nested Class)——小区里的独立商铺

比喻:商铺开在小区里,但不属于任何住户(不持有外部类引用)。

特点:

  • 不依赖外部类实例:可直接创建 new Outer.Inner()
  • 不能访问外部类非静态成员

代码示例:

class Outer {  
    private static String staticMsg = "静态消息";  
    private String instanceMsg = "实例消息";  

    static class Inner {  
        void print() {  
            System.out.println(staticMsg); // 可以访问外部类静态成员  
            // System.out.println(instanceMsg); // 编译错误!不能访问非静态成员  
        }  
    }  
}  

public static void main(String[] args) {  
    Outer.Inner inner = new Outer.Inner(); // 直接创建  
    inner.print();  
}  

总结口诀:

“静态属性共享用,静态方法工具人。
静态代码块初始化,静态内部类不依赖。
滥用静态埋大坑,合理使用是灵魂!”