Java基础(十)——内存分析(入门了解)和异常处理

Java基础(十)——内存分析(入门了解)和异常

一、内存分析

1、初步了解

一个简单的Java文件,从编译运行开始,到中间的main方法执行,实例化对象,赋值等等一系列操作,中间内存都发生了什么变化呢?先举个简单的例子:
在这里插入图片描述

看左边的代码,下面的都是普通的定义,get、set方法以及toString。上面都是实例化对象,赋值,以及输出语句。

右边的图中,分三个区域,分别是栈、堆、方法区。栈:放了栈帧和局部变量,其中 main 方法在栈里面有额外的一个区来存储,叫栈帧。堆中主要负责:实例化对象。方法区中主要:常量池,静态化和字节码文件。

接着就是代码运行时,内存中的一些操作:
在这里插入图片描述
其中要注意的是:
1、局部变量的一个特点,用完即销毁。
2、基本数据类型是直接赋值。
3、引用数据类型是指向或者引用。

方法不调用的时候是不存在的,需要用到方法的时候根据字节码文件再创造出来,方法的主体准确来说是放在栈里面,虽然用完了下次再用还是同一个方法名,但是已经不一样了;可以说即是一样又是不一样。

只要记住,堆中对象只存放属性。

2、例题1(对象)

思考:这里打印出来的结果会是什么?
在这里插入图片描述

先上分析:
在这里插入图片描述

a、分析:属性部分

代码从上到下运行,所以(上图懒得画属性写在方法区中的常量池):
第一行代码,堆中实例化对象 new Student ("zs"18),接着栈帧中Student stu1指向堆中 zs 所在的对象;第二行代码同理。

接着就是栈帧中 int age = 18:
在这里插入图片描述

b、分析:第一个方法

接着就到了方法1,stu1传递到了方法中的形参,stu1指向的是zs,所以方法中的 stu 指向的是zs,然后执行 setAge()方法,把 age 改成了10,:
在这里插入图片描述

接着 栈中下面的 Student stu 用完即销毁:
在这里插入图片描述

c、分析:第二个方法(重点)

方法二中的形参,接收的是 ls 对象,所以这里的 Student stu 指向的是 ls。但是,里面的代码又 new 了一个对象,所以堆中要开辟一个新的空间,原本的 stu 指向的是 ls ,这里重新指向了 ww 。然后就到了 setAge()方法,这里因为指向的是 ww ,所以修改的是 ww 的年龄;然后修改完后就销毁。
在这里插入图片描述

d、分析:第三个方法

这里形参接收的是全局的 age ,所以是 18,接着方法里面给 age 赋值30,这里赋值的是方法里面的局部变量,赋值完毕后整体销毁。所以这里全局变量 age ,还是18。

3、例题2(数组对象)

在这里插入图片描述
左右两边代码只有部分不一样。思考打印出来的结果是什么?

左右两边的代码唯一不同的地方在于,for 循环内外的 new Student 这一块。

a、分析左图代码

核心在于:new Student 在 for 循环里面这一块,for 循环三次,会开辟三个新的空间,原本的三个数组分别指向了三个新的对象。这时候数组里面的三个对象内容都是 name:z6,age:18.。接着 for 循环结束后,执行名字重新赋值,数组里第一个对象名字改为 张三,其他都不变:
在这里插入图片描述

b、分析右图代码

这一部分的代码,new Student 在 for 循环的外面,意味着三次循环都不会开辟新的空间。通过 for 循环,让数组里面三个对象,都统一指向了 stu 这个对象
在这里插入图片描述
这时候关键就来了,for循环结束后,stus[0].setName(“张三”),这语句把名字修改成张三,但是因为这时候数组里三个对象都指向了 stu 这个对象,所以修改的是 stu 里面的名字,所以三个对象的名字都同时修改了。

4、总结例题2

1、数组里3个引用不同的对象。

2、数组里3个引用相同的对象。

二、异常

1、异常初了解

每一个程序员不可避免的就是程序报错,也就是程序出现异常。异常种类多种多样

Throwable:异常和错误的父类
Error:错误
Exception:异常

当递归无限调用自己,就会报错异常,这种叫栈溢出错误:
在这里插入图片描述

在这里插入图片描述

2、常见异常

异常一般分为两种:
1、受检性异常(一般异常):编译时期出现异常(一般语法有问题,或者有异常需要你去处理的这种是受检性异常)

2、非受检性异常(运行时异常):运行时期出现的异常

a、数组索引越界异常

举例子:
在这里插入图片描述

下标超出了,出现错异常:
在这里插入图片描述

不懂英文可以查看翻译:

在这里插入图片描述

b、空指针异常

在这里插入图片描述

equal()方法是对比字符串是否一样的方法。这里面括号内的空,跟 null 不是同一个东西。

养成良好习惯,把对象写括号里面,这样就算 str 为null,也不会报错:
在这里插入图片描述

c、类型转换异常

还有个前面讲过的,动物类和猫类狗类,猫变狗会报错:
在这里插入图片描述

d、算术异常

0不能作为分母这种算术异常:
在这里插入图片描述

三、异常处理

1、try…catch捕获异常

a、了解使用

捕获异常语法:
在这里插入图片描述
以往程序出现异常,到了出错部分往往就停止了,后面有代码也不会再运行。当有了捕获异常后,就算有异常,后面的代码还能继续运行:
在这里插入图片描述
在这里插入图片描述

但是原本的异常信息没有了,这里还是可以打印:
在这里插入图片描述
在这里插入图片描述

b、try块出现异常后续代码不再执行

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

c、何时使用捕获异常

当知道如何处理异常的时候使用 try catch

2、throws—抛出(声明)异常

抛出异常归抛出异常,但是异常的后续代码一样不会执行。

在这里插入图片描述

3、RuntimeException—自定义异常

需要先继承RuntimeException这个类。
在这里插入图片描述
上图可以看到,MyException 是自己写的异常,出现异常可以根据自己写的内容显现出来。但是后面的代码,也同样没有执行,程序同样会终止。

自定义异常:throw
抛出异常对象,会使程序中止。

4、finally——一定会执行的代码块

finally 是无论出现什么异常,一定都会执行里面的代码块的功能。
在这里插入图片描述

其中,这里面不一定要跟着 catch ,可以直接 try…finally:
在这里插入图片描述

这个代码执行的是 -1。正常来说到 return 就结束了,但是因为有 finally,所以会执行到 finally 部分再结束。

猜你喜欢

转载自blog.csdn.net/qq_41824825/article/details/121210353
今日推荐