java中的static关键字说清楚还得靠JVM

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

前言

  • Java中Static想必大家一定使用过吧。他是用来修饰类或者成员变量或者方法的。
  • 关于Static的用法还是很简单的,因为他就是一个修饰词。但是如果不理解他修饰的作用原理的话,可能会闹出bug来

变量

image-20220509191420226.png

  • 上图是一个简化的JVM内存结构模型。学习过JVM的都知道我们创建的对象正常情况下都是在堆中的。那么我们访问对象中的属性自然也就存放在堆中的。
  • 但是当static修饰属性之后他就发生了变化了。
 ​
 class Demo {
   //成员变量
   public int num = 100;
   //静态成员变量
   public static int count = 200;
   //静态方法
   public static void method(){
     System.out.println(count);
   }
 }
复制代码
  • num属性属于常规属性,count属性属于静态变量。他们不仅仅是名称上的不同。从JVM的角度看他的存放位置也不同。
  • 首先num依赖于具体的对象,所以他和对象存放在一起都是堆中。
  • 而count独立于对象。JVM中专门有一块空间用于存放静态变量。这个空间我们叫做方法区。

方法

  • 除了修饰变量外,static还可以修饰方法。被修饰的方法我们叫做静态方法 。静态方法的特点和静态变量一样都属于类而不是对象。静态方法内部只能访问静态变量而无法通过this对象进行访问对象属性。
  • 总结下来就是静态方法内部只能访问静态变量无法访问非静态变量。
  • 除了静态方法外,还有一个特殊的方法叫做静态代码块。这个方法不需要我们准备方法名,入参,出参等等。只需要准备方法体。关于方法体内部和静态方法内部要求是一样的。

image-20220514140752124.png

  • 关于静态代码块和静态方法他们和普通方法还有一个重要的区别就是执行时机。静态变量与普通变量的区别就是内存分布位置,而方法是在栈中操作的,不涉及内存的存储,所以区别就是方法执行的时机。这里需要我们提前了解点类加载机制。
  • 首先我们一个类的加载分为五个过程。首先是加载class元信息,最后一步是进行初始化。至于前面三步我们这里可以不理解。重点知道在类加载的最后阶段会进行初始化,而初始化的操作就是执行静态方法和静态代码块。
  • 从类加载过程中我们也能够看的出来静态方法是不依赖于对象的调用的。因为静态方法中只能使用到静态属性。也就是说静态属性使用时还没有创建对象。这也佐证了静态变量不依赖对象的说法。

总结

  • 本文主要讲解Java基础,请原谅我没有华丽的词藻渲染出色的文章。虽然基础但往往是我们容易忽略的知识点。
  • 只有不断的学习,才能不断的进步,关于static的进一步使用场景,目前我能想到的就是单例模式中会使用。

猜你喜欢

转载自juejin.im/post/7103332427287756831