Java关键字static的6个常见误区及解决方法

 更新时间:2026年05月13日 09:08:47   作者:希望永不加班  
文章主要讲述了Java中static关键字的常见误解和误区,包括static属于类而非对象、静态方法不能被重写、静态方法中不能使用this或super、静态代码块只会执行一次、static变量并非天生线程安全以及要在声明或静态块中初始化静态变量等内容,需要的朋友可以参考下

static 是 Java 入门最早接触、却也是误解最多的关键字。很多同学只会用它写静态常量、静态方法,但对生命周期、继承、重写、初始化顺序、this 能否使用、线程安全等认知模糊,日常写 Bug、面试翻车,大多都是踩了 static 的坑。

误区一:static 属于对象,而不是属于类

错误认知

静态变量、静态方法是归每个对象所有,创建越多实例,静态变量就有多份副本。

正确原理

1. static 修饰的成员,全局只一份,归属于类,不属于任何对象

2. 类加载阶段就初始化,优先于对象存在,所有实例共享同一个静态变量。

3. 无论 new 多少个对象,静态变量内存中永远只有一份。

反例代码

public class StaticDemo {
    public static int count = 0;
    public StaticDemo(){
        count++;
    }
}

连续 new 三次对象,count 直接累加到 3,而不是每个对象各自为 1。

结论

静态资源全局唯一、对象共享,跟实例数量无关。

误区二:静态方法可以被重写(Override)

错误认知

父类有静态方法,子类写一个同名同参静态方法,就是重写。

正确原理

1. 静态方法不能被重写,只能被隐藏(Hide)

2. 静态方法编译期静态绑定,由引用类型决定调用哪个方法,而不是运行时对象类型。

3. 多态对 static 完全失效

示例对比

class Father{
    public static void show(){
        System.out.println("父类静态方法");
    }
}
class Son extends Father{
    public static void show(){
        System.out.println("子类静态方法");
    }
}
public class Test{
    public static void main(String[] args) {
        Father f = new Son();
        f.show(); // 输出:父类静态方法
    }
}

如果是普通实例方法,会走多态调用子类;静态方法看引用类型,不看实际对象

结论

静态方法只可隐藏、不可重写,不具备多态特性。

误区三:静态方法中可以直接使用 this、super

错误认知

普通方法能用 this,静态方法也能用 this 访问成员。

正确原理

1. thissuper 代表当前实例对象

2. 静态方法属于类,不需要对象就能调用,执行时可能根本没有实例。

3. 因此静态方法禁止使用 this、super,也不能直接调用普通实例方法、直接访问实例变量。

编译报错代码

public static void test(){
    this.xxx(); // 编译直接报错
}

结论

静态上下文与实例无关,不能出现任何对象相关关键字。

误区四:静态代码块只会执行一次,随便写都没问题

错误认知

静态代码块随时都会执行,或者每次 new 对象都会执行。

正确原理

1. 静态代码块:类加载时执行,全局只执行一次

2. 执行时机早于构造器、早于普通代码块。

3. 只会在类首次被加载、主动使用时触发一次,后续 new 对象不再执行。

4. 坑:静态块里不要写耗时逻辑、数据库连接、死循环,会直接拖慢项目启动、导致卡死。

执行顺序

静态代码块 → 普通代码块 → 构造方法

结论

静态块随类加载只跑一次,适合初始化常量、加载配置,禁止写耗时业务逻辑。

误区五:static 变量天然线程安全

错误认知

静态变量全局只有一份,自带同步,多线程修改也不会有并发问题。

正确原理

1. static 只是全局共享一份内存不具备任何原子性、可见性、有序性保障

2. 多线程同时读写静态变量,依然会出现脏数据、覆盖丢失、竞态条件

3. 静态变量反而更容易引发并发 Bug,因为所有线程共享同一份。

并发错误示例

public class CountUtil{
    public static int num = 0;
    public static void add(){
        num++;
    }
}

多线程循环累加,结果一定小于预期,典型线程不安全。

正确做法

静态变量并发修改需要:synchronized / AtomicInteger / Lock 保证线程安全。

结论

static ≠ 线程安全,共享变量反而更容易出并发问题。

误区六:可以在普通代码块/构造器中给静态变量随意初始化

错误认知

静态变量在哪赋值都一样,构造器、普通代码块随便改。

正确原理

1. 静态变量属于类,本该在:静态代码块、声明处初始化。

2. 在构造器、普通代码块给静态变量赋值:

  • 每 new 一次对象,就会重新覆盖静态值;
  • 极易造成全局状态被意外篡改,隐藏极深的 Bug。

3. 违背设计语义:静态资源不该依赖实例创建来初始化。

坑示例

public class User{
    public static String type;
    public User(){
        type = "user";
    }
}

只要 new 一次,就强行覆盖静态变量,全局状态被随意改动。

结论

静态变量尽量在声明或静态块初始化,不要在构造器、实例代码块中赋值。

全文总结

这 6 个误区,既是日常开发高频坑,也是 Java 面试常问原题。

1. static 归不归对象,全局唯一共享;

2. 静态方法不可重写、只能隐藏,无多态;

3. 静态上下文不能用 this / super,不能直接访问实例成员;

4. 静态代码块类加载仅执行一次,禁止耗时逻辑;

5. static 变量不自带线程安全,多线程必须加同步;

6. 静态变量尽量静态环境初始化,不要在构造器中乱赋值。

以上就是Java关键字static的6个常见误区及解决方法的详细内容,更多关于Java static关键字常见误区的资料请关注脚本之家其它相关文章!

相关文章

  • Java开发到底为什么要用 IoC 和 AOP

    Java开发到底为什么要用 IoC 和 AOP

    这篇文章主要介绍了Java开发到底为什么要用 IoC 和 AOP,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-02-02
  • SpringBoot如何获取当前操作用户的id/信息

    SpringBoot如何获取当前操作用户的id/信息

    在一般性的基设需求中,有需要获取当前用户操作记录的情况,也就是说我们需要记录当前用户的信息,如:id、昵称、账号等信息,这篇文章主要介绍了SpringBoot获取当前操作用户的id/信息,需要的朋友可以参考下
    2023-10-10
  • Java中comparator接口和Comparable接口的比较解析

    Java中comparator接口和Comparable接口的比较解析

    这篇文章主要介绍了Java中comparator接口和Comparable接口的比较解析,Java提供了一个用于比较的接口Comparator和Comparable接口,提供了一个比较的方法,所有实现该接口的类,都动态的实现了该比较方法,需要的朋友可以参考下
    2023-08-08
  • Java和Redis实现热搜功能

    Java和Redis实现热搜功能

    这篇文章主要介绍了Java和Redis实现热搜功能,在存储和传输用户搜索数据时,考虑到数据的机密性和隐私保护,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • Jedis出现connection timeout问题解决方法(JedisPool连接池使用实例)

    Jedis出现connection timeout问题解决方法(JedisPool连接池使用实例)

    这篇文章主要介绍了Jedis出现connection timeout问题解决方法,使用Jedis的JedisPool连接池解决了这个问题,需要的朋友可以参考下
    2014-05-05
  • java Date类详解及使用总结

    java Date类详解及使用总结

    这篇文章主要介绍了java Date类详解及使用总结的相关资料,需要的朋友可以参考下
    2017-02-02
  • 简单了解JAVA public class与class区别

    简单了解JAVA public class与class区别

    这篇文章主要介绍了简单了解JAVA public class与class区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • @Valid和@Validated注解校验以及异常处理方式

    @Valid和@Validated注解校验以及异常处理方式

    在Javaweb开发中,防止数据库恶意攻击是至关重要的,尽管前端校验可以起到一定的筛选作用,但通过工具如postman直接对后端发起请求的情况仍然需要后端进行严格的数据校验,Java生态下,@Valid注解配合SpringBoot提供了一个便捷高效的后端数据校验方案
    2024-11-11
  • SpringBoot3整合SpringDoc实现在线接口文档的详细过程

    SpringBoot3整合SpringDoc实现在线接口文档的详细过程

    这篇文章主要介绍了SpringBoot3整合SpringDoc实现在线接口文档的详细过程,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • MyBatis一对多嵌套查询的完整实例

    MyBatis一对多嵌套查询的完整实例

    这篇文章主要给大家介绍了关于MyBatis一对多嵌套查询的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论