JAVA-初步认识-第七章-this关键字内存图解
一.
对于静态的使用和注意事项已经讲解过了,接下来用一个例子,把静态所涉及的内存区域用图的形式给大家展现一下。
这里面进行了一个Person的描述,里面有两个成员变量name,age,同时有一个静态的变量country。接下来Person当中给我们提供了一个构造函数,能同时初始化性能和年龄。接下来还有一个非静态的方法show,可以显示出这个人的个人信息。接下来还有一个静态方法,它可以去显示我们国籍。
主函数中我们先用类名的形式调用了静态方法,紧接着创建了该类的对象,该类的对象调用了一个非静态的方法,这个方法只能被静态调用。
上面的例子中,主函数里面的语句Person p=new Person(); 这里显示括号里没有任何参数。在描述类中,没有空参数的构造函数,这里也就无法进行构造函数初始化。
以上面的描述为例,来将内存中的过程展现一下。(我觉着这里还是想将学到现在的所有面向对象知识点串起来,理清先后顺序。)
上面的截图内容挺不同寻常的,没有进行编译StaticDemo2的源程序,而是直接用java命令运行了StsticDemo2的类。就是说,没有编译就运行了?
这是在运行一个类,这个类就会被加载进内存,至于这个类被封装对象的过程,现在讲不了。这个部分到后面才能讲到。一加载进来就要进行空间的开辟。
无论怎样,计算机内存早就被划分为几个部分,来分别存储不同的东西。目前涉及的内存区域主要有三个,栈,堆,方法区。
区域划分完毕后,数据都在哪?是个问题。
方法存在哪?方法都存放在方法区里。解析一下,方法是如何在方法区存放的。
当StaticDemo2这个类被执行的时候,其实这个类就进内存了(程序运行都是在内存中操作的)。这个类一进内存,就开辟空间了。
在方法区划分了一片空间,存储StaticDemo2的类,分完以后,这个类里面有一个成员方法,就是StaticDemo2(),这个方法搞不清楚是哪来的?这个方法是这个类中的默认构造函数。会随着类一起加载进来。
主函数是静态的,main()会被加载入静态区,专门存储静态的数据。静态区里也会标明是StaticDemo2的类,然后里面有static main()的方法。
上面一左一右,左边是非静态区,右边是静态区。非静态区的方法和静态区的方法都是被共享的。为什么?以描述类中的show()方法而言,所有的对象都具备这功能,唯一的不同是什么?就是对象所封装的数据不一样。有的对象叫张三,有的对象就李四,但是大家都会说话,都会说的自己姓名和年龄,所以这个功能是共享的,这个功能就在方法区里面。只不过方法区分静态和非静态,因为调用方式和所属的不一样。非静态区域里面所有的成员都有一个this所属。为什么?非静态的内容只能被对象调用。而到了静态区,它有都有所属的类名。
在控制台上,将java StaticDemo2一回车,它就加载完了。加载完了,虚拟机就直接使用这个类名,调用方法。这个时候,main方法就进栈。main方法进栈以后,它就要运行里面内容,但是main方法里面的代码是存储在静态区。因为,源程序中的所有东西都被转换成了字节码文件存储起来了。mian本身就在静态区,它的代码也在静态区。
第一句Person.show()使用到了一个类,这个时候,这个类才加载。这个时候就去找,classpath路径下是否有Person.class文件。如果没有设置classpath,它就默认在当前目录下找,找到以后,就会把person.class文件加载进内存。一加载就会在方法区,分配空间了。Person类就进内存了,紧跟着Person的构造函数,以及show方法。它们加载完以后,static method的方法也会加载进来,这个方法所属Person类。这是我们所说的静态区,都是共享数据。紧接着,这里面还没完,里面还有country,country默认初始化为null,接着初始化为"CN",
加载完以后,是Person.method(),是类名在调用。用类名调用,只能找静态区。到静态区一找,在Person这个类所属的静态区当中或者说在静态区当中有Person类,Person类区域当中,有没有main方法呢?有的话,method的方法就进栈了。这个方法持有this么?没有,只有非静态区的才有this。到目前为止,堆里面没有东西。注意,method的方法从方法区里的静态区,到了栈内存中。下面的右截图的虚线是代码存放区,有的也叫做方法表。栈中的method是运行区,里面会有局部变量,运行完释放。栈区中存放方法的局部变量,System.out.println是不进来的,
方法进栈完以后,它就开始运行,运行的时候,就开始执行方法行动代码。有变量就开辟空间,没变量空间开辟完以后就会释放。一运行,Person.country就输出了,它在调用country这个一个变量。发现这个变量是类名.,如果不写类名.的话,class文件里也有。调用的时候,是找person里静态变量,一找到,就把CN给输出了。输出完以后,再往下就是return;method方法就弹栈了,到这呢,这个方法区就加载完毕了。
接着就执行第二句,Person p=new Person("java", 20); 接着主函数里面就多了个p,=右边是一个Person。堆内存中就开辟空间,分配地址编号,加载成员变量,默认初始化值。当然在类的描述当中,它可以描述描述自己的name和age,但是存在类型被使用,必须存到对象当中,因为这个name和age值是只能在对象中存在的。默认初始化完毕后,要接着构造函数初始化。这时,就要回头找,相对应的构造函数。这个时候,构造函数就进栈了,而这个构造函数在访问对象中的数据,它在给对象中的数据进行初始化。给哪个对象初始化呢?它不知道,所以它里面就持有一个this,而这时正好是0x0056的对象在调用构造函数,所以this等于0x0056. 紧跟着它的name就被赋值为”java“,age就被赋值为”20“,。紧跟着,这个函数完事以后,开始执行,构造函数里面的代码,this.name=name, this.age=age,一致性时,发现构造函数里面的name赋值给this.name,而this是0x0056的对象,也就是name=”java“赋值给了对象中的name。
这时候,构造函数就完毕了,它就要弹栈了。紧跟着,右边堆中的对象初始化就结束了。接着就把地址编号0x0056赋值给左边p,这样一来,p就指向了对象。
最后,执行p.show(),调用show方法。在方法区的非静态区有show方法。注意:在p.show在编译的时候,它会检查的源文件是否有show,没有的话,就编译失败了。可是运行的时候,它也会检查,发现有show,就让show进栈。show是非静态的,show得有this所属0x0056,执行里面代码,发现没有局部变量,只有输出语句。就直接执行输出语句。在输出的时候,发现输出country,大家都知道在counrty在编译完以后,在生成class文件,就已经有类名所属,所以它就找静态区里面的内容。找完以后,就打印了CN。接着找寻name和age的值,name和age前面有this,打印的都是0x0056的值,指向对象中的name和age值。找到以后,就输出了,CN,java,20.输出完以后,show方法就弹栈。
它弹栈以后,主函数的最后一句话就是return,这是默认,隐式,写不写都可以,系统会自动帮你加上,函数要结束。构造函数有return语句,一般方法有return语句。只有void的情况,return才可以省略。主函数有renturn,也弹栈。接着没有代码了,虚拟机结束了。这里面涉及线程。
转载于:https://www.cnblogs.com/wsw-bk/p/7668739.html
JAVA-初步认识-第七章-this关键字内存图解相关推荐
- 构建高性能ASP.NET站点 第七章 如何解决内存的问题(后篇)—托管资源优化—监常用优化措施...
构建高性能ASP.NET站点 第七章 如何解决内存的问题(后篇)-托管资源优化-监常用优化措施 前言:有段时间没有写这个系列了,希望大家见谅,本篇主要将会介绍一些常用的CLR优化措施. 本篇的议题 ...
- 第七个猴子java_黑猴子的家:Java SE 练习题第七章
尾部都有答案 第七章练习题(多态) (1)下列自'关多态的叙述正确的是哪项?(选两项) A. 父类的引用指向子类的实例是一种多态 B. 子类的引用指向子类的实例是一种多态 C. 接口的引用指向实现该接 ...
- 【JAVA SE】第七章 继承和多态
第七章 继承和多态 文章目录 第七章 继承和多态 一.继承 1.概念 2.继承的特性 2.继承关键字 3.构造器 4.子类重写父类方法的规则 二.多态 1.概念 2.多态的优点 3.多态存在的三个必要 ...
- JAVA语言程序设计第七章
第七章:输入输出 7.1流式输入输出 两种基本流:InputStream(输入流), OutputStream(输出流) 根据流相对于程序的另一个端点不同可分两类: NodeStream(节点流/基层 ...
- java学习笔记-第七章:面向对象编程(基础部分)
第七章:面向对象编程(基础部分) 总体内容 类与对象 引出类与对象 类与对象概述 类与对象的关系示意图 属性概念及其细节 类与对象快速入门案例 对象内存布局 类与对象内存分配机制 引申:java内存的 ...
- 使用java实现面向对象 第七章
第七章 多线程 一.Thread类和Runnable接口 1.在java.lang包中定义了Runnable接口和Thread类. Runnable接口中只定义了一个方法,它的格式为: public ...
- java第六、七章复习
面向对象认知概述 面向对象思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,同时了解这些对象具有哪些相应的属性及行为,以解决这些对象面临的一些实际问题,面向对象设计实质上就是对现实世界的 ...
- java中this图解_JAVA-初步认识-第七章-this关键字的使用场景和原理图解
一. this有什么用?我们用例子的形式来体现一下. 下面的截图说明,给人对象一初始化的时候,赋值个姓名.赋值姓名的时候,拿n赋值给name, DOS显示创建对象时,构造函数初始化成功. 在例子中,我 ...
- esp8266接收到的数据如何存放到数组中_愉快地学Java语言:第七章 数组
导读 本文适合Java入门,不太适合Java中高级软件工程师.本文以<Java程序设计基础篇>第10版为蓝本,采用不断提出问题,然后解答问题的方式来讲述.本篇文章只是这个系列中的一篇,如果 ...
- java 并发编程第七章:取消和关闭
Java没有提供任何机制来安全地终止线程,虽然Thread.stop和suspend等方法提供了这样的机制,但是存在严重的缺陷,应该避免使用这些方法.但是Java提供了中断Interruption机制 ...
最新文章
- Ferris教程学习笔记:js示例2.13 简易JS年历
- 如何判断一个对话机器人有多智能?
- 最高标号预留与推进算法 --- 就是要比 Dinic 快!
- bootstrap设置button不显示_电脑便签怎么显示不关闭?电脑云便签敬业签怎么设置显示桌面?...
- 电赛 | 电源题软件如何准备?
- 第二章 数据的表示和运算 2.1.3 字符与字符串 [计算机组成原理笔记]
- 详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节
- 转:完整的最简单的谱聚类python代码
- 2019牛客暑期多校训练营(第二场)A(随机化)
- ai google 风格化图像_谷歌 AI 新方法:可提升 10 倍图像识别效率,关键还简单易用...
- 安卓udp发包工具_好装逼牌udp-tcp发包工具
- android 反编译jar包
- 计算机的网络测速,电脑怎么网络测速
- 快门光圈感光度口诀_怎么利用光圈快门感光度
- photo的复数是photos
- 2022年全球颈椎按摩仪市场前景分析及研究报告
- android 自动打开wifi热点
- conv1d(): argument ‘padding‘ (position 5) must be tuple of ints, not str 这个错误是怎么回事呀?请各位帮忙看看,万分感谢
- 如何设计好一条推送通知
- hue ensure called on an unitialized