关于static关键字的两个易错点

1、为什么局部变量不能使用static关键字修饰?
内存分为三大块,栈内存,堆内存和方法区内存。栈内存主要存放局部变量和对象的内存地址(通过引用保存起来),堆内存主要存放对象本身以及成员变量,方法区内存主要存放class相关信息以及static修饰的静态变量。由于staitc关键字修饰的变量是属于类共有的,因此不可能修饰局部变量,因为局部变量仅隶属于一个方法当中,出了这个方法就不能访问了。当栈内存中的方法执行完成,该方法以及方法内的局部变量所占据的内存空间就会释放。关于静态变量为什么属于类,而不属于对象,可以参考以下实例:
在这里插入图片描述
如图所示,栈内存中有个main方法,在main方法中如果调用m1()方法,在m1()方法中调用m2()方法,会发生压栈。栈活动的原则是:后进先出,先进后出。在发生弹栈过程的时候,栈内存中的方法,局部变量全部得到释放。假如现在有一个专门调查中国人口的Person类,这个类里的成员方法有名字,身份证号和国籍,当然,每个人的姓名,身份证号都不一样,但是国籍都是一样的。如果我们在国籍上不加static,那么国籍这个成员变量是属于对象的,也就是,每创建一次对象,都要为国籍赋值,这样,每个对象中都会保存一份String nationality的成员变量,但事实是,String nationality的值都是“中国”,如果让每个对象都持有一份的话,太浪费内存了。因此,如果在String nationality前用static关键字修饰,让它变成静态变量,属于这个类共有的变量,以后创建对象的时候就不用专门为国籍赋值了,访问不需要用引用.变量名的方式,而是用类名.变量名的方式去访问即可。这个时候,这个变量会从堆内存转移到方法区内存中,为所有的对象所共有,内存布局会变成这样:
在这里插入图片描述
这也从一定意义上解释了为什么局部变量不能使用static关键字修饰。

2、关于静态数据既可以使用类名.变量名的方式访问,也可以用引用.变量名的方式访问。
在这里插入图片描述
如上图,静态方法正规方法是通过类名.变量名的方式去访问,但是也可以通过引用.变量名的方式去访问。如下图:
在这里插入图片描述
实际上,虽然创建了对象,但在编译阶段,JVM检查出s是StaticTest类型,并且m1方法是静态方法,因此还是采用了类名.变量名的方式执行。整个过程并没用到对象。这个理论可以通过一个实例去验证,大家都知道空指针异常,也就是空引用访问成员会出现异常。这个时候,我们先让s的值为null,再去调m1()方法,结果如下:
在这里插入图片描述
如果所示,结果并没有出现空指针异常。原因是m1方法是静态的,程序会自动通过类去访问,而不是通过引用,因此就不存在空指针的说法。

猜你喜欢

转载自blog.csdn.net/weixin_44734925/article/details/89325167
今日推荐