一.

对于静态的使用和注意事项已经讲解过了,接下来用一个例子,把静态所涉及的内存区域用图的形式给大家展现一下。

这里面进行了一个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关键字内存图解相关推荐

  1. 构建高性能ASP.NET站点 第七章 如何解决内存的问题(后篇)—托管资源优化—监常用优化措施...

    构建高性能ASP.NET站点 第七章 如何解决内存的问题(后篇)-托管资源优化-监常用优化措施   前言:有段时间没有写这个系列了,希望大家见谅,本篇主要将会介绍一些常用的CLR优化措施. 本篇的议题 ...

  2. 第七个猴子java_黑猴子的家:Java SE 练习题第七章

    尾部都有答案 第七章练习题(多态) (1)下列自'关多态的叙述正确的是哪项?(选两项) A. 父类的引用指向子类的实例是一种多态 B. 子类的引用指向子类的实例是一种多态 C. 接口的引用指向实现该接 ...

  3. 【JAVA SE】第七章 继承和多态

    第七章 继承和多态 文章目录 第七章 继承和多态 一.继承 1.概念 2.继承的特性 2.继承关键字 3.构造器 4.子类重写父类方法的规则 二.多态 1.概念 2.多态的优点 3.多态存在的三个必要 ...

  4. JAVA语言程序设计第七章

    第七章:输入输出 7.1流式输入输出 两种基本流:InputStream(输入流), OutputStream(输出流) 根据流相对于程序的另一个端点不同可分两类: NodeStream(节点流/基层 ...

  5. java学习笔记-第七章:面向对象编程(基础部分)

    第七章:面向对象编程(基础部分) 总体内容 类与对象 引出类与对象 类与对象概述 类与对象的关系示意图 属性概念及其细节 类与对象快速入门案例 对象内存布局 类与对象内存分配机制 引申:java内存的 ...

  6. 使用java实现面向对象 第七章

    第七章 多线程 一.Thread类和Runnable接口 1.在java.lang包中定义了Runnable接口和Thread类. Runnable接口中只定义了一个方法,它的格式为: public ...

  7. java第六、七章复习

    面向对象认知概述 面向对象思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,同时了解这些对象具有哪些相应的属性及行为,以解决这些对象面临的一些实际问题,面向对象设计实质上就是对现实世界的 ...

  8. java中this图解_JAVA-初步认识-第七章-this关键字的使用场景和原理图解

    一. this有什么用?我们用例子的形式来体现一下. 下面的截图说明,给人对象一初始化的时候,赋值个姓名.赋值姓名的时候,拿n赋值给name, DOS显示创建对象时,构造函数初始化成功. 在例子中,我 ...

  9. esp8266接收到的数据如何存放到数组中_愉快地学Java语言:第七章 数组

    导读 本文适合Java入门,不太适合Java中高级软件工程师.本文以<Java程序设计基础篇>第10版为蓝本,采用不断提出问题,然后解答问题的方式来讲述.本篇文章只是这个系列中的一篇,如果 ...

  10. java 并发编程第七章:取消和关闭

    Java没有提供任何机制来安全地终止线程,虽然Thread.stop和suspend等方法提供了这样的机制,但是存在严重的缺陷,应该避免使用这些方法.但是Java提供了中断Interruption机制 ...

最新文章

  1. Ferris教程学习笔记:js示例2.13 简易JS年历
  2. 如何判断一个对话机器人有多智能?
  3. 最高标号预留与推进算法 --- 就是要比 Dinic 快!
  4. bootstrap设置button不显示_电脑便签怎么显示不关闭?电脑云便签敬业签怎么设置显示桌面?...
  5. 电赛 | 电源题软件如何准备?
  6. 第二章 数据的表示和运算 2.1.3 字符与字符串 [计算机组成原理笔记]
  7. 详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节
  8. 转:完整的最简单的谱聚类python代码
  9. 2019牛客暑期多校训练营(第二场)A(随机化)
  10. ai google 风格化图像_谷歌 AI 新方法:可提升 10 倍图像识别效率,关键还简单易用...
  11. 安卓udp发包工具_好装逼牌udp-tcp发包工具
  12. android 反编译jar包
  13. 计算机的网络测速,电脑怎么网络测速
  14. 快门光圈感光度口诀_怎么利用光圈快门感光度
  15. photo的复数是photos
  16. 2022年全球颈椎按摩仪市场前景分析及研究报告
  17. android 自动打开wifi热点
  18. conv1d(): argument ‘padding‘ (position 5) must be tuple of ints, not str 这个错误是怎么回事呀?请各位帮忙看看,万分感谢
  19. 如何设计好一条推送通知
  20. hue ensure called on an unitialized

热门文章

  1. VLAN的分类与实验
  2. Kubernetes详解(九)——资源配置清单创建Pod实战
  3. 单元测试实践的主要问题与解决(2)
  4. Luminus模板可选项
  5. ExtJs UI框架学习五
  6. Effective C# 原则42:使用特性进行简单的反射(译)
  7. jqgrid 固定列宽度_jqGrid 设置列宽
  8. java 存储多叉树_JAVA多叉树森林的构造、内存存储与遍历
  9. 用unity协程写的发牌程序
  10. 201903版的idea markdown无法预览的问题