栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 部分再结束。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/445727.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号