从内存方面分析Java中static关键字
在java中static关键字的作用主要是用来修饰变量,方法,代码块。成员变量分为实例变量和类变量,使用static关键字修饰的成员变量即为类变量,使用static修饰的方法即为类方法,使用static修饰的代码块即为static代码块。
学过java的小伙伴一定都知道在java中,内存主要是划分为程序计数器,本地方法栈,虚拟机栈,堆,方法区,而程序计数器和本地方法栈跟static关键字联系不大这里不做讨论,这里主要从栈,堆和方法区来分析(方法区是堆区中的一个部分)。这里我用一张图片来展示每个区中包含的信息。
在我们执行一个程序的时候,java虚拟机会先加载方法区中的内容,如果遇到static代码块,则立即运行。也就是说,使用static关键字修饰的内容在对象还未创建之前就已经分配好了内存,这也是我们为什么能够直接使用类名.方法或类名.变量名去调用类变量和类方法的原因,也是为什么我们不能在类方法中使用实例变量和普通方法的原因。
我下面举一个例子来帮助大家理解上面的内容
public class A{
static int a = 10;//这是一个类变量
int b;//这是一个实例变量
public void prins(){
int d;//这是一个局部变量
}
public static void prin(){//这是一个类方法
System.out.println(a);//输出类变量a
}
public static void main(String[] args){
Test c = new A();//创建一个对象c
c.prins();//调用普通方法prins
A.prin();//调用类方法prin
System.out.println(A.a);//输出类变量a
}
static {
System.out.println("这是一个静态代码块");
}
}
在程序运行时,java虚拟机会先进行初始化,将A的类信息,类变量a,类方法prin()加载到方法区,并运行static代码块,打印出“这是一个静态代码块”。然后才会进入main方法中,进行创建对象c,调用方法以及其他操作。
方法区中的内容只会创建一次,因为静态变量是创建在方法区中,因此只会创建一次并分配一次内存,因此无论创建多少个对象,静态变量和静态方法只会创建一次,只是将静态变量的地址给了对象而已,因此当我们通过对象名.类变量或者类名.类变量调用类变量并修改它的值的时候,其他对象调用的类变量的值也都会修改。