欢迎光临散文网 会员登陆 & 注册

Java零基础快速入门|对象的创建和使用(上)

2021-02-04 15:34 作者:动力节点小王本王  | 我要投稿



本篇文章主要内容:

对象的创建和使用

Java虚拟机内存管理

学习目标

理解构造方法以及重载机制,通过构造方法可以完成对象的创建,并且能够通过引用访问对象的内存,了解 Java 虚拟机内存管理,能够画出程序执行过程的内存图,并了解空指针异常是如何发生的,以及方法调用时参数是如何传递的。

 

知识框架


对象的创建和使用

对象的创建

类定义之后,就可以使用类这个“模板”来创造“对象”了,一个类是可以创建多个对象的哦!怎么创建呢,语法是什么?其实语法格式很简单:new 类名(),这样就可以完成对象的创建了。俗话说,你想要什么java 都可以给你,想要啥你就new 啥。请看下面代码:

为了使用对象更加方便,建议使用变量接收一下?例如以下代码:

以上代码最初接触的时候,大家肯定会感觉非常陌生,这也是正常的,Student s1 = new Student()实际上和int i = 10 是类似的,对于 int i = 10 来说,int 是一种基本数据类型,i 是变量名,10 int 类型的字面量。那对于 Student s1 = new Student()来说,其中Student 是一种引用数据类型,s1 是变量名,new Student()执行之后是一个Student 类型的对象。

大家要注意了,java 语言当中凡是使用 class 关键字定义的类都属于引用数据类型,类名本身就是这种引用数据类型的类型名。

对象的使用

创建了对象之后怎么去访问这个对象的属性呢,或者说学生对象现在有了,怎么去访问他的学号、姓名、性别、年龄等信息呢。请看以下代码:

运行结果如下图所示:

对象的创建和使用


接下来解释一下以上的输出结果,通过以上的 Student 类可以创建很多学生对象,假设通Student 类实例化了两个学生对象,那必然会有两个不同的学号,以上程序中并没有给学号赋值,但是获取了到的学号都是0,这是怎么回事呢?

这是因为在java 语言当中,当实例变量没有手动赋值,在创建对象的时候,也就是说在 new 的时候,系统会对实例变量默认赋值, 它们的默认值请参考下表:


对象创建和使用的深层次解密

 java 虚拟机内存管理

为了更好的理解上面的程序,先来看看java 虚拟机是如何管理它的内存的,请看下图:

java 虚拟机内存管理


① 程序计数器:

1) 概念:可以看做当前线程所执行的字节码的行号指示器。

2) 特点:线程私有的内存

java 虚拟机栈(重点):

1) 概念:描述的是 java 方法执行的内存模型。每个方法在执行的时候会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用直至完成的过程,就对应一个栈帧从入栈到出栈的过程。

2) 特点: 线程私有, 生命周期和线程相同。 这个区域会出现两种异常: StackOverflowError 异常: 若线程请求的深度大于虚拟机所允许的深度。OutOfMemoryError 异常:若虚拟机可以动态扩展,如果扩展是无法申请到足够的内存。

③ 本地方法栈:

1) 概念:它与虚拟机栈所发挥的作用是相似的,区别是 java 虚拟机栈为执行java 法服务,而本地方法栈是为本地方法服务。

2) 特点:线程私有,也会抛出两类异常:StackOverflowError OutOfMemoryError

④ java 堆(重点):

1) 概念:是被所有线程共享的一块区域,在虚拟机启动时创建。

2) 特点:线程共享,存放的是对象实例所有的对象实例和数组),GC 管理的主要区域。可以处于物理上不连续的内存空间。

方法区(重点):

1) 概念:存储已被虚拟机加载的类信息、常量、静态变量,即时编译器编译后的代码等数据。

2) 特点:线程共享的区域,抛出异常OutOfMemory 异常:当方法区无法满足内存分配需求的时候。

以上所描述内容,有看得懂的,也有看不懂的,例如:线程、本地方法等,这个需要大家在学习后面内容之后,返回来再看一看,那个时候你就全部明白了。针对于目前来说,大家必须要知道 java 虚拟机有三块主要的内存空间,分别是“虚拟机栈后面简称栈)”、“方法区”、“堆区”,方法区存储类的信息,栈中存储方法执行时的栈帧以及局部变量,堆区中主要存储 new 出来的对象,以及对象内部的实例变量。其中垃圾回收器主要针对的是堆内存, 方法区中最先有数据,因为程序执行之前会先进行类加载。栈内存活动最频繁,因为方法不断的执行并结束,不断的进行压栈弹栈操作。

将目前阶段需要掌握的内存空间使用一张简单的图表示出来,这个图是大家需要掌握的:

java 虚拟机内存管理简图

大概了解了java 虚拟机内存分配之后,来看看以下代码在执行过程中,内存是如何变化的:

以上代码在执行过程中内存的变化如下图所示:

第一步进行类加载
第二步main 方法调用,给main 方法分配栈帧(压栈)


第三步执行int i = 10,局部变量

第四步执行new Student(),在堆中创建对象,同时初始化实例变量
第五步将堆区中学生对象的内存地址赋值给局部变量s1

注意:上图所描述内存图有些地方为了帮助大家更好的理解,有些位置画的不是很精确, 随着后面内容的学习我们再进一步修改,目前上图已经够大家用了。

上图中i 变量和 s1 变量都是局部变量,都在栈内存当中,只不过i 变量是基本数据类型ints1 变量是引用数据类型Student

上图中堆区当中的称为“对象”,该“对象”内部 nonameagesex 都是实例变量/属性,这些变量在new 对象的时候初始化,如果没有手动赋值,系统会赋默认值。

上图堆区中“对象”创建完成之后,该对象在堆区当中的内存地址是:0x1111,程序中的=”将0x1111 这个堆内存地址赋值给s1 变量,也就是说 s1 变量保存了堆内存对象的内存地址,我们对于这种变量有一种特殊的称呼,叫做“引用”。也就是说对于 Student s1 = new Student() 代码来说,s1 不是对象,是一个引用,对象实际上是在堆区当中,s1  变量持有这个对象的内存地址。

java 中没有指针的概念指针是 C 语言当中的机制,所以 java 程序员没有权利直接操作堆内存,只能通过“引用”去访问堆内存中的对象,例如:s1.nos1.names1.sexs1.age访问一个对象的内存,其实就是访问该对象的实例变量,而访问实例变量通常包括两种形式, 要么就是读取数据,要么就是修改数据,例如:System.out.println(s1.no)这就是读取数据,s1.no= 100 这就是修改数据。请看以下代码:

运行结果如下所示:

修改实例变量之后的执行结果

执行了以上程序之后,堆内存对象的实例变量发生了变化,如下图所示:

实例变量执行赋值运算之后的内存图

如果基于以上的代码再创建一个对象,内存图会是怎么的呢?先看代码:

JVM 内存结构图如下所示:

创建多个对象的内存结构图

 

通过上图的学习,可以看出假设 new 100 个学生对象,会有 100 no100 age...是这样吧。

通过以上内容的学习,需要每位同学掌握:局部变量存储在哪里?实例变量存储在哪里? 实例变量在什么时候初始化?对象和引用有什么区别?在 java 中怎么访问堆内存当中的对象?这些你都掌握了吗?


最后附Java零基础视频教程给大家,配合学习效果更佳!!



Java零基础快速入门|对象的创建和使用(上)的评论 (共 条)

分享到微博请遵守国家法律