从零学Java 异常
2024-01-10 11:33:24
Java 异常
文章目录
1 异常的概念
概念:程序在运行过程中出现的特殊(不正常)情况。
异常处理的必要性:任何程序都可能存在大量的未知问题、错误;
如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。
2 异常的分类
Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。
2.1 错误
Error: JVM、硬件、执行逻辑错误,不能手动处理。
- StackOverFlowError: 栈空间溢出错误
- OutOfMemoryError: 堆空间溢出错误
2.2 异常
Exception:程序在运行和配置中产生的一般问题,可处理。
- RuntimeException:运行时异常,可处理,可不处理。
- 【CheckedException】:检查(编译)时异常,必须处理,除了RuntimeException其它都是检查(编译)时异常。
2.3 常见运行时异常
类型 | 说明 |
---|---|
NullPointerException | 空指针异常 |
ArrayIndexOutOfBoundsException | 数组越界异常 |
ClassCastException | 类型转换异常 |
NumberFormatException | 数字格式化异常 |
ArithmeticException | 算术异常 |
3 异常的产生
当程序在运行时遇到不符合规范的代码或结果时,会产生异常。
出现异常相当于遇到 return 语句,导致程序因异常而终止。
4 异常的传递
异常的传递:按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)并中断程序。
eg:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at StageOne.day16.Exception.Test.main(Test.java:17)
5 异常处理关键字
关键字 | 说明 |
---|---|
try | 可能出现异常的代码 |
catch | 捕获异常 |
finally | 异常最终处理,释放资源 |
throw | 抛出异常 |
throws | 声明异常 |
6 常见异常处理结构
6.1 try{ } catch{ } 结构
三种情况:
- 正常执行
- 出现异常并处理
- 异常类型不匹配
语法:
try {
//可能出现异常的代码
} catch(Exception e) {
//异常处理的相关代码,如:getMessage()、printStackTrace()
}
eg:
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int r = 0;
try {
System.out.println("请输入第一个数: ");
int i = input.nextInt();
System.out.println("请输入第二个数: ");
int i1 = input.nextInt();
r = i/i1;
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("结果是: "+r);
}
}
6.2 try{ } catch{ } finally{ } 结构
语法:
try {
//可能出现异常的代码
} catch(Exception e) {
//异常处理的相关代码,如:getMessage()、printStackTrace()
}finally{
//是否发生异常都会执行,可以释放资源等...
}
注:
- finally块是否发生异常都执行,可以资源释放等。
- finally块不执行的唯一情况,提前退出Java虚拟机
eg:
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int r = 0;
try {
System.out.println("请输入第一个数: ");
int i = input.nextInt();
System.out.println("请输入第二个数: ");
int i1 = input.nextInt();
r = i/i1;
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("最总处理, 释放资源");
}
System.out.println("结果是:"+r);
}
}
6.3 try{ } catch{ } catch{ }…结构
语法:
try{
//可能出现异常的代码
}catch(异常类型1){
//满足异常类型1执行的相关代码
}catch(异常类型2){
//满足异常类型2执行的相关代码
}catch(异常类型3){
//满足异常类型3执行的相关代码
}
注:
- 子类异常在前,父类异常在后
- 发生异常时按顺序逐个匹配,只执行第一个与异常类型匹配的catch语句
eg:
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int r = 0;
try {
System.out.println("请输入第一个数: ");
int i = input.nextInt();
System.out.println("请输入第二个数: ");
int i1 = input.nextInt();
r = i/i1;
} catch (ArithmeticException e) {
System.out.println("算术异常");
} catch (InputMismatchException e) {
System.out.println("输入不匹配异常");
} catch (Exception e) {
System.out.println("未知异常");
}
System.out.println("结果是: "+r);
}
}
6.4 try{ } catch{ } catch{ } finally{ }结构
语法:
try{
//可能出现异常的代码
}catch(异常类型1){
//满足异常类型1执行的相关代码
}catch(异常类型2){
//满足异常类型2执行的相关代码
}finally{
//是否发生异常都会执行,可以释放资源等...
}
eg:
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int r = 0;
try {
System.out.println("请输入第一个数: ");
int i = input.nextInt();
System.out.println("请输入第二个数: ");
int i1 = input.nextInt();
r = i/i1;
} catch (ArithmeticException | InputMismatchException e) {
System.out.println("算术异常或输入不匹配异常");
} catch (Exception e) {
System.out.println("未知异常");
} finally {
System.out.println("最终处理,释放资源");
}
System.out.println("结果是: "+r);
}
}
6.5 try{ } finally{ } 结构
try…finally…不能捕获异常,仅仅用来当发生异常时,用来释放资源。
一般用在底层代码,只释放资源不做异常处理,把异常向上抛出。
语法:
try{
//可能出现异常的代码
}finally{
//是否发生异常都会执行,可以释放资源等...
}
eg:
public class Test01 {
public static void main(String[] args) {
try {
divide();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("程序结束了...");
}
public static void divide() {
Scanner input = new Scanner(System.in);
int r = 0;
try {
System.out.println("请输入第一个数: ");
int i = input.nextInt();
System.out.println("请输入第二个数: ");
int i1 = input.nextInt();
r = i/i1;
} finally {
System.out.println("最终处理,释放资源");
}
System.out.println("结果是: "+r);
}
}
6.6 面试题
- try{}、catch{}、finally{}中是否可以包含return语句?
? 答: 语法上都可以, 但不推荐在finally中写, 否者会输出错误的数据
- 如果try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会执行?
? 答: 会执行
-
以下代码返回多少?并说明执行过程。
eg:
public class Test02 { public static void main(String[] args) { System.out.println(getNum()); } public static int getNum() { int num = 10; try { return num++; } catch (Exception e) { return num++; } finally { num++; } } } res: 10 public class Test02 { public static void main(String[] args) { System.out.println(getNum()); } public static int getNum() { int num = 10; try { return num++; } catch (Exception e) { return num++; } finally { return num++; } } } res: 11
7 throws - 声明异常
如果在一个方法体中抛出了异常,如何通知调用者?
throws关键字:声明异常,通知调用者此方法有异常。
使用原则:底层代码向上声明或者抛出异常,最上层一定要处理异常,否则程序中断。
注意事项:
- (1)如果方法抛出的是检查时异常,调用者必须处理,如果是运行时异常,可以不处理(不建议, 都要处理)。
- (2)可以声明抛出多个异常类型,中间用逗号隔开。
eg:
public class Test01 {
public static void main(String[] args) {
try {
divide();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("程序结束了...");
}
//throws:声明异常,告诉调用者有异常
public static void divide() throws Exception {
Scanner input = new Scanner(System.in);
int r = 0;
System.out.println("请输入第一个数: ");
int i = input.nextInt();
System.out.println("请输入第二个数: ");
int i1 = input.nextInt();
r = i / i1;
System.out.println("结果是"+r);
}
}
8 throw - 抛出异常
除了系统自动抛出异常外,有些问题需要程序员自行抛出异常。
throw关键字:抛出异常
语法: throw 异常对象;
eg:
在setAge(int age)中对年龄进行判断,如果年龄介于1到100直接赋值,否则抛出异常。
在setGender(String gender)中对性别进行判断,如果性别是男或女直接赋值,否则抛出异常
在测试类中创建对象并调用setAge(int age)方法,使用try...catch捕获并处理异常。
Student:
public class Student {
private int age;
private String gender;
public Student(int age, String gender) throws Exception {
this.setAge(age);
this.setGender(gender);
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception{
if (age<1 || age>100) {
throw new Exception("异常年龄输入");
} else {
this.age = age;
}
}
public String getGender() {
return gender;
}
public void setGender(String gender) throws Exception {
if (gender.equals("男")||gender.equals("女")) {
this.gender = gender;
} else {
throw new Exception("异常性别输入");
}
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
TestStudent:
public class TestStudent {
public static void main(String[] args) {
Student stu = null;
try {
stu = new Student(120, "男");
} catch (Exception e) {
System.out.println("数据异常, 请重新输入...");
}
System.out.println(stu);
}
}
9 自定义异常
概念:需继承Exception或Exception的子类,代表特定问题。
经验:异常类型名称望文生义,可在发生特定问题时抛出对应的异常。
eg:
public class AgeException extends RuntimeException{
public AgeException() {
}
public AgeException(String message) {
super(message);
}
}
public class GenderException extends RuntimeException{
public GenderException() {
}
public GenderException(String message) {
super(message);
}
}
10 带有异常声明的方法重写
规则:
- 子类继承父类,方法名、参数列表、返回值类型必须和父类相同。
- 子类的访问修饰符和父类相同或是比父类更宽。
- 子类中的方法,不能抛出比父类更多、更宽的检查时异常。
文章来源:https://blog.csdn.net/weixin_50858647/article/details/135497131
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!