JavaSE基础
一、异常
1.1 异常概述
- 程序运行过程中出现了不正常【报错】的情况
1.2 异常处理的必要性
- 任何程序都可能存在未知的异常,可能造成不必要的损失
1.3 异常的分类
Throwable
Throwable
类是 Java 语言中所有错误或异常的超类。- 只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java
throw
语句抛出。 - 类似地,只有此类或其子类之一才可以是
catch
子句中的参数类型。 - 两个子类的实例,
Error
和Exception
,通常用于指示发生了异常情况。
Error
- 用于指示合理的应用程序不应该试图捕获的严重问题。
- 虚拟机错误、配置错误、线程死亡错误、、、
- 无法通过代码处理的异常
Exception
-
它指出了合理的应用程序想要捕获的条件。
-
开发者能处理 && 需要处理的异常
-
索引越界、空指针异常、算术运算异常、类型转换异常、、、
-
因为代码或者配置产生的异常,需要处理
RuntimeException(运行时异常)
- 可以不处理
CheckedException(检查异常)
- 必须处理
1.4 异常的产生
- 虚拟机抛出
- 手动抛出
public class Main {
public static void main(String[] args) {
// 虚拟机抛出异常
// System.out.println(10 / 0);
int age = 1130;
if (age<0 || age>130) {
// System.out.println("年龄非法");
// 手动抛出异常
throw new RuntimeException("年龄非法");
}
}
}
1.5 异常传递
- 异常是会传递给调用者的
- 按照方法的调用链反向传递
- 如果异常一直没有得到有效的处理,最终传递给JVM,JVM抛出异常并打印信息
- 按照方法调用链反向打印堆栈追踪信息
package com.exception;
public class TestException01 {
public static void main(String[] args) {
/**
* main >>> show01 >>> show02 >>> show03
* show03 <<< show02 <<< show01 <<< main
*/
System.out.println("main方法开始...");
show01();
System.out.println("main方法结束...");
}
public static void show01() {
System.out.println("show01方法开始...");
show02();
System.out.println("show01方法结束...");
}
public static void show02() {
System.out.println("show02方法开始...");
show03();
System.out.println("show02方法结束...");
}
public static void show03() {
System.out.println("show03方法开始...");
System.out.println(10/0);
System.out.println("show03方法结束...");
}
}
/**
main方法开始...
show01方法开始...
show02方法开始...
show03方法开始...
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.exception.TestException01.show03(TestException01.java:28)
at com.exception.TestException01.show02(TestException01.java:22)
at com.exception.TestException01.show01(TestException01.java:16)
at com.exception.TestException01.main(TestException01.java:10)
异常层层递进,一般第一行就是离错误最近的地方
/*
二、异常处理【重点】
2.1 异常处理语法
try{
可能出现异常的代码
} catch(异常01 e){
处理异常代码块01
} catch(异常02 e){
处理异常代码块02
} catch(异常03 e){
处理异常代码块03
}... {
} finally{
无论是否出现异常都要执行的代码
}
package com.exception;
import java.util.InputMismatchException;
import java.util.Scanner;
public class TestException02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
try {
int num = sc.nextInt();
System.out.println(10 / num);
} catch(InputMismatchException e) {
// 打印堆栈追踪信息
e.printStackTrace();
} catch (ArithmeticException e) {
// e.printStackTrace();
System.err.println("算术运算异常");
} finally {
System.out.println("必须执行的代码");
}
}
}
/**
请输入一个整数:
a
java.util.InputMismatchException
必须执行的代码
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at com.exception.TestException02.main(TestException02.java:11)
*/
2.2 finally
- 无论是否遇到异常都会执行的代码
package com.exception;
import java.util.InputMismatchException;
import java.util.Scanner;
public class TestException02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
try {
int num = sc.nextInt();
System.out.println(10 / num);
} catch(ArithmeticException e) {
System.err.println("正在处理异常...");
return;
//System.exit(0); // 终止虚拟机 ,finally不会执行
} finally {
System.out.println("必须执行的代码...");
}
}
}
/**
return
请输入一个整数:
0
正在处理异常...
必须执行的代码...
/
2.3 final,finalize,finally三者区别
1、final可以修饰类,变量,方法,修饰的类不能被继承,修饰的变量不能重新赋值,修饰的方法不能被重写。
2、finally用于抛异常,finally代码块内语句无论是否发生异常,都会在执行finally,常用于一些流的关闭。
3、finalize方法用于垃圾回收。
三、自定义异常
3.1 概述
- 官方的异常有时候无法准确表示我们项目中的异常【见名知意】
- 开发者可以模仿JDK中的异常来自定义异常
3.2 流程
- 1)创建一个类继承Exception或者RuntimeException
- 2)调用父类中有参数和无参数的构造方法
- 3)在合适的位置抛出异常
IllegalAgeException
package com.exception;
public class IllegalAgeException extends RuntimeException {
public IllegalAgeException(String s) {
super(s);
}
public IllegalAgeException() {
super();
}
/**
*
*/
private static final long serialVersionUID = 1L;
}
Student
package com.exception;
public class Student {
private String name;
private Integer age;
public Student() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
if (age>0 && age<130) {
this.age = age;
} else {
try {
throw new IllegalAgeException();
} catch (IllegalAgeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
Main
package com.exception;
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("张三");
stu.setAge(23);
System.out.println(stu);
// 设置非法年龄触发异常
stu.setAge(244);
System.out.println(stu);
}
}