【Java 异常】try-catch、finally、异常的种类、throws、thorw、自定义异常、断言类

本文详细探讨了Java中关于null值的打印、异常处理(包括检查型和非检查型异常,try-catch,finally和throws关键字的使用),以及如何防止程序因异常终止运行。作者还介绍了自定义异常和Java异常体系结构。
摘要由CSDN通过智能技术生成

思考:下面代码的打印结果是什么?

public static void main(String[] args) {

Integer[] nums = { 11, null, 22 };

for (int num : nums) {

System.out.println(num);

}

}

在这里插入图片描述

Integer 在自动拆箱为 int 时,会调用 Integer 对象的 inValue() 方法;

由于 nums[1]null,使用 null 调用方法会抛出一个异常

  • 异常类型:java.lang.NullPointerException

  • 由于没有主动去处理这个异常,所以导致程序终止运行

上面抛出异常的代码建议这么写:

Integer[] nums= { 11, null, 22 };

for (Integer num : nums) {

System.out.println(num);

}

打印的细节

Java 中直接打印 null 会报错;

在这里插入图片描述

但是有时候确实可以把 null 打印出来:

public class Dog {

@Override

public String toString() {

return “Dog - 666”;

}

}

Dog dog = new Dog();

System.out.println(dog); // Doge - 666

Dog dog2 = null;

System.out.println(dog2); // null

为什么 null 能被打印出来呢?可以看一下 println 的底层实现:发现调用了 String.valueOf

public void println(Object x) {

String s = String.valueOf(x);

synchronized (this) {

print(s);

newLine();

}

}

再看看 String.valueOf:可以发现打印出 null 其实是经过处理的。

public static String valueOf(Object obj) {

return (obj == null) ? “null” : obj.toString();

}

异常(Exception)

================================================================================

Java 中有各种各样的异常

  • 所有的异常最终都继承自 java.lang.Throwable

在这里插入图片描述

如何防止程序因为抛出异常导致终止运行?

  • 可以通过 try-catch 来捕捉处理异常

try-catch


在这里插入图片描述

思考:下面代码的打印结果是什么?

public static void main(String[] args) {

System.out.println(1);

try {

System.out.println(2);

Integer i = new Integer(“abc”);

System.out.println(3);

} catch (NumberFormatException e) {

System.out.println(4);

}

System.out.println(5);

}

1

2

4

5

一个 catch 捕获多种类型的异常

try {

} catch(异常A | 异常B | 异常 C) {

// 当抛出【异常A】或【异常B】或【异常C】类型的异常时,会进入这个代码块

}

  • 从 Java 7 开始,单个 catch 可以捕获多种类型的异常

  • 如果并列的几个异常类型之间存在父子关系,保留父类型即可

  • 这里的变量 e 是隐式 final 的

异常对象的常用方法(getMessage、printStackTrace)


try {

Integer integer = new Integer(“abc”);

} catch (NumberFormatException e) {

// 异常描述

System.out.println(e.getMessage());

// 异常名称 + 异常

System.out.println(e);

// 打印堆栈信息

e.printStackTrace();

}

在这里插入图片描述

finally


trycatch 正常执行完毕后,一定会执行 finally 中的代码:

  • finally 可以和 try-catch 搭配使用,也可以只和 try 搭配使用

  • 经常会在 finally 中编写一些关闭、释放资源 的代码(比如关闭文件)

在这里插入图片描述

finally 细节:

如果在执行 trycatch 时,JVM 退出或者当前线程被中断、杀死

  • finally 可能不会执行

如果 trycatch 中使用了 returnbreakcontinue 等提前结束语句

  • finally 会在 returnbreakcontinue 之前执行

思考:下面代码的打印结果是什么?

for (int i = 1; i <= 3; i++) {

try{

System.out.println(i + “_try_1”);

if (i == 2) continue;

System.out.println(i + “_try_2”);

} finally {

System.out.println(i + “_finally”);

}

}

1_try_1

1_try_2

1_finally

2_try_1

2_finally

3_try_1

3_try_2

3_finally

for (int i = 1; i <= 3; i++) {

try{

System.out.println(i + “_try_1”);

if (i == 2) break;

System.out.println(i + “_try_2”);

} finally {

System.out.println(i + “_finally”);

}

}

1_try_1

1_try_2

1_finally

2_try_1

2_finally

public static void main(String[] args) {

System.out.println(get());

}

static int get() {

try {

new Integer(“abc”);

System.out.println(1);

return 2;

} catch (Exception e) {

System.out.println(3);

return 4;

} finally {

System.out.println(5);

}

}

3

5

4

异常的种类(检查型异常、非检查型异常)


在这里插入图片描述

检查型异常(Checked Exception)

  • 这类异常一般难以避免,编译器进行检查

如果开发者没有处理这类异常,编译器将报错

  • 哪些异常是检查型异常?

ErrorRuntimeException 以外的异常

非检查型异常(Unchecked Exception)

  • 这类异常一般可以避免,编译器不会进行检查

如果开发者没有处理这类异常,编译器将不会报错

  • 哪些异常是非检查型异常?

ErrorRuntimeException

常见的检查型异常

在这里插入图片描述

常见的非检查型异常 – Error

在这里插入图片描述

常见的非检查型异常 – RuntimeException

在这里插入图片描述

throws(作用、流程、细节)


throws 的作用:将异常抛给上层方法

void test() throws FileNotFoundException, ClassNotFoundException {

PrintWriter out = new PrintWriter(“F:/mj/520it.txt”);

Class cls = Class.forName(“Dog”);

}

如果 throws 后面的异常类型存在父子关系,保留父类型即可

void test() throws Exception {

PrintWriter out = new PrintWriter(“F:/mj/520it.txt”);

Class cls = Class.forName(“Dog”);

}

void test() throws Throwable {

PrintWriter out = new PrintWriter(“F:/mj/520it.txt”);

Class cls = Class.forName(“Dog”);

}

可以一部分异常使用 try-catch 处理,另一部分异常使用 throws 处理:

void test() throws FileNotFoundException {

PrintWriter out = new PrintWriter(“F:/mj/520it.txt”);

try {

Class cls = Class.forName(“Dog”);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

thorws 的流程

  • 如果异常最终抛给了 JVM,那么整个 Java 程序将终止运行

下面这个例子中,异常从 method1 开始网上抛,到 method2,再到 method3,最后抛给 mainmain 又抛给了 JVM;

public static void main(String[] args) throws ClassNotFoundException {

method1(); // 正常来说, 这里必须处理异常了, 否则出异常后Java程序会终止运行

}

static void method1() throws ClassNotFoundException {

method2(); // 这里可以处理异常

}

static void method2() throws ClassNotFoundException {

method3(); // 这里可以处理异常

}

static void method3() throws ClassNotFoundException{

Class clazz = Class.forName(“Dog”); // 这里可以处理异常

}

在这里插入图片描述

所以如果一直不处理异常,只往上抛最终会导致程序停止运行,一定要在某个地方处理异常。

throws 的细节

当父类的方法没有 throws 异常:子类的重写方法也不能 throws 异常

当父类的方法有 throws 异常,子类的重写方法可以:

  • throws 异常

  • throws 跟父类一样的异常

  • throws 父类异常的子类型

public class Person {

public void test1() {}

public void test2() throws IOException {}

public void test3() throws IOException {}

public void test4() throws IOException {}

public void test5() throws IOException {}

}

public class Student extends Person {

@Override

public void test1() {}

@Override

public void test2() {}

@Override

public void test3() throws IOException {}

@Override

public void test4() throws FileNotFoundException {}

// 只能抛出父类异常的子类, 或者不抛

// public void test5() throws Exception {} // 抛出子类异常的父类异常, 会报错

}

throw


使用 throw 可以抛出一个新建的异常

public class Person {

public Person(String name) throws Exception { // 抛出异常

if (name == null || name.length() == 0) {

// 检查型异常必须处理或者往上抛

throw new Exception(“name must not be empty.”);

}

}

}

public class Person {

public Person(String name) {

if (name == null || name.length() == 0) {

// 非检查型异常可以不处理

throw new IllegalArgumentException(“name must not be empty.”);

}

}

}

自定义异常(Exception、RuntimeException)


开发中自定义的异常类型,基本都是以下 2 种做法:

  • 继承自 Exception

使用起来代码会稍微复杂

希望开发者重视这个异常、认真处理这个异常(该异常无法从代码层面去避免,必须引起重视)

  • 继承自 RuntimeException

使用起来代码会更加简洁

不严格要求开发者去处理这个异常(因为规范的代码可以避免该异常)

示例:

自定义两种异常:EmptyNameExceptionWrongAgeException

public class EmptyNameException extends RuntimeException {

public EmptyNameException() {

super(“name must not be empty”);

}

}

public class WrongAgeException extends RuntimeException {

private int age;

public WrongAgeException(int age) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

小编利用空余时间整理了一份《MySQL性能调优手册》,初衷也很简单,就是希望能够帮助到大家,减轻大家的负担和节省时间。

关于这个,给大家看一份学习大纲(PDF)文件,每一个分支里面会有详细的介绍。

image

这里都是以图片形式展示介绍,如要下载原文件以及更多的性能调优笔记(MySQL+Tomcat+JVM)!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
何学起的朋友,同时减轻大家的负担。**[外链图片转存中…(img-Kn6RVpjZ-1713524691663)]

[外链图片转存中…(img-TZ5PrLQI-1713524691665)]

[外链图片转存中…(img-0deFGyf2-1713524691668)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

小编利用空余时间整理了一份《MySQL性能调优手册》,初衷也很简单,就是希望能够帮助到大家,减轻大家的负担和节省时间。

关于这个,给大家看一份学习大纲(PDF)文件,每一个分支里面会有详细的介绍。

[外链图片转存中…(img-hTGFWZdB-1713524691670)]

这里都是以图片形式展示介绍,如要下载原文件以及更多的性能调优笔记(MySQL+Tomcat+JVM)!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值