小变量大学问 干了这杯全家桶

java零基础入门-面向对象篇(七)  各种变量在JVM中的位置和运行方式

本章对前面学的知识进行一个总结,为下面要介绍的封装继承和多态打好基础。

学习就要不断的复习和总结,才能让学过的知识不断的得到沉淀,变成自己的知识,切勿心浮气躁,囫囵吞枣。

在我的编程生涯中,遇到过很多问题和BUG,最让我难忘的就是那种既不报错,又没有异常的BUG,这种BUG解起来让人痛苦不堪,比如我当年就碰到过一个由static 静态变量引发的BUG,最后只能用输出语句排查,这就是典型的知识点掌握的不牢引发的问题。当然那段代码不是我写的。

所以在我们使用变量的时候,一定要掌握一些原则,就是潜规则,不能随便看心情来定义变量。如果能够知道变量的内在原理,那对我们写代码会有更大的帮助。

变量的分类

根据变量的声明位置一般分为两种

类里面方法外面声明的变量,是成员变量。成员变量又分为类变量实例变量。类变量就是static修饰的变量,它属于类。实例变量就是没有static修饰的变量,它属于对象。

再就是在方法内部声明的变量,是局部变量。局部变量包括方法的参数,方法内部定义的变量。


变量分类

1.普通成员变量,属于对象

2.静态成员变量,属于类

3.局部变量,方法的参数是局部变量

4.方法内部定义的变量是局部变量

前面说堆栈的时候,说变量在栈里面,其实那仅仅是指局部变量。普通成员变量在堆里面,静态成员变量在方法区。是不是又有点懵,就一个变量整这么多地方干啥,东放一点西放一点,放一起不就完了。其实分开存放是有原因的,因为他们的生命周期不同,不同的变量有着不同的生命周期,导致他们必须存放在不同的地方。

为什么生命周期不同要放不同的地方?你想想你家有冰箱吧,你试试不把冰淇淋放冰箱,估计你还没吃,它就变成液体了。因为冰淇淋的生命周期不同,它不在冰箱活不了多久,要根据它的特点指定存放的地方,不然你还没开始调用(吃),他就被销毁了(化了)。


栈帧

首先来看局部变量,局部变量是生命周期最短的,为什么呢?因为局部变量一般定义在方法里面,他随着方法的调用创建,随着方法的完毕销毁。

我们前面说的栈是一种数据结构,它是一种设计概念,而我们虚拟机里面的虚拟机栈是用这个设计概念实现的程序,请不要混淆两者的概念。

现在我们可以完善一下前面讲的那个栈的结构了。在JVM中,我们每次入栈其实不是入栈的一个变量,而是一个栈帧,在我们知识体系不完善的时候用入栈变量来解释可能会好理解一些,但是现在我们储备了足够的知识,我们就可以理解的更准确一点。

栈帧是什么?栈帧是虚拟机进行方法调用和方法执行的数据结构。就是说,我们每一个方法,都对应了一个栈帧。

栈帧主要由以下几个部分组成,局部变量表,操作数栈,动态连接,方法返回地址。这里我们只关注局部变量表,其他几个部分,知道有这个东西就行了。


栈帧的组成


对我们来说,栈帧里面最需要了解的就是局部变量表。我们方法中定义的局部变量,就是参数和方法内定义的变量都存在这里(第一张图里面,3,4)。下面我们来看看调用方法的时候,栈帧是怎么进出的。

1.当方法执行到 studyFrameWork 这个方法的时候,栈帧入栈。方法的局部变量 frameWork 和 spring 在栈帧的局部变量表中,一起入栈。

1


2.当studyFrameWork这个方法执行完毕后,方法对应的栈帧出栈。

2


3.当程序继续运行到下一个方法 studyWebFrameWork 的时候,这个方法对应的栈帧入栈,并且这个方法的局部变量 webFrameWork 和 vue 保存在局部变量表,一同入栈。

3


以上这个类是将两个方法分开执行的情况,我们再看看下面这种情况

1.调用方法 studyAllFrameWork 的时候,局部变量 frameWork 和 spring 在局部变量表中入栈

1


2.这个时候,studyAllFrameWork 这个方法没有执行完毕,在这个方法内部又再次调用了 studyWebFrameWork 这个方法,局部变量vue,webFrameWork 在局部变量表中入栈。这个时候栈中有两个栈帧,先入栈的在栈底,后入栈的在栈顶。

2


3.后入栈的方法执行完毕,返回值返回给先入栈的方法,这个时候后入栈的方法出栈,程序继续执行。

3


4.最后当第一个入栈的方法也执行完毕后,第一个方法对应的栈帧也出栈了。

4


看到这里,很多同学心里的问题应该有答案了。

为什么只有栈顶可以操作?我直接用栈底的数据不行吗?

因为当我们调用方法的时候,方法中的数据按照顺序入栈,如果没有运行完毕或者出现异常,这个方法对应的栈帧是不会出栈的,如果往下执行,又调用了另外一个方法,那么另外一个方法对应的栈帧会继续入栈,在栈顶,然后程序开始执行后入栈的这个栈帧对应的方法,所以只有栈顶的这个栈帧对应的方法才可以操作,当他运行完毕出栈以后,会继续运行第一个没有运行完毕的方法,这时候,第一个方法对应的栈帧就是栈顶(因为只有一个栈帧了)。所以只有栈顶可以操作。

当然,如果我们第二个方法中又调用了第三个方法,就会有第三个方法对应的栈帧入栈。然后依次运行,出栈。

入栈的时候,局部变量开始生效,出栈的时候,局部变量就销毁掉了,所以局部变量的生命周期只在方法内部有效,出了方法就不能使用了。现在大家应该对这个有更深刻的理解了吧。


成员变量的位置

成员变量

成员变量有两种,普通成员变量属于对象,因为当我们使用 new 创建一个对象的时候,这个对象会在堆里面开辟一个空间,而成员变量会随着这个对象的创建,也在堆里面。而当程序里面没有任何变量指向这个对象的时候,这个对象就会被清洁阿姨回收掉,这个时候成员变量也会一起被回收掉。

所以普通成员变量的生命周期和对象一样,随着对象的创建而创建,随着对象的回收而回收。

再看另外一种,静态成员变量。静态成员变量在方法区,它属于类,所以它的生命周期跟类一样。也就是说当对象生老病死以后,这个静态成员变量依然活的好好的。

本文开头说过一个静态变量引发的BUG就是,某位不知名程序员为了满足一个 “全局” 的需求,结果使用了静态变量,然后他每次 new出来的对象都会对这个全局变量进行修改, 由于方法区是线程共享的,结果出现了意料之外的结果。所以理解每种变量所在区域和该区域的特点很有必要。

对于各种变量,我们知道它们的生命周期和作用范围,对我们后面的学习很有必要。比如我们要控制变量的作用范围,可以使用局部变量的时候就使用局部变量,过多的使用成员变量会增加堆内存的开销。再就是我们讲到封装等概念的时候,也需要控制变量的作用范围,使我们的程序更加符合程序设计的规范。

最后,本章解释的jvm栈帧结构其实也不是很完全,但是作为初学者,学这些已经远远超出了我们需要掌握的知识,能理解最好,实在不能理解也没有关系。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容

  • 说到梦想,我感觉在我的世界里它是不断变化的,小时候老师都会问长大的梦想是什么,老师啊医生啊这样的词汇都出来了,再到...
    忆昔rlm阅读 26,480评论 0 0
  • 你的沉默像一尊雕像 打碎它,无数眼泪飞了出来 叶片沉郁,阳光欠身刺入 晚风掀开帷幕 灯火自虚门飞出 飞出瞳孔、脑袋...
    王圣钦阅读 154评论 0 0