1、异常是什么?
异常就是模拟现实中不正常的事件。
2、异常的作用?
告诉你具体的位置帮助进行数据处理。
3、异常的分类?
异常可分为:
(1)Error异常,程序发生错误不可处理,直接退出JVM。
(2)Exception异常,程序发生异常可处理,若无及时处理,则退出JVM。
共同点:他们的父类为Thorwable,意为可抛出的
4、Exception如何处理?
Exception又分为编译时异常和运行时异常;
运行时异常(RuntimeException):所有RuntimeException的子类都为运行时异常,程序员不需要进行处理。
编译时异常:Exception的直接子类都为编译时异常;编译时异常需要程序员对其进行处理,可在方法名的变量上进行throws关键字向上抛出,也可以用try…catch…进行捕捉。
5、Exception处理。
(1)throws处理(假处理):FileInputStream是IO包下的一个类,该类构造方法throws FileNotFoundException,导致异常,感兴趣的朋友可以去JDK的API文档看看。
import java.io.*;
public class ThrowsText02 {
public static void main(String[] args){
FileInputStream fis = new FileInputStream("abc.txt");
}
}
此时代码报错:编译无法通过
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type FileNotFoundException
at p03.Exception.ThrowsText02.main(ThrowsText02.java:16)
使用throws关键字处理:
import java.io.*;
public class ThrowsText02 {
public static void main(String[] args) throws Exception{
FileInputStream fis = new FileInputStream("abc.txt");
}
}
运行结果为:编译通过
Exception in thread "main" java.io.FileNotFoundException: abc.txt (系统找不到指定的文件。)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:110)
at p03.Exception.ThrowsText02.main(ThrowsText02.java:16)
**个人理解:throws像是把问题丢给上面的人(父类)去解决,我不管这个问题,只要我想要的效果有了就行!
**(2)深入throws
import java.io.*;
public class ThrowsText03 {
public static void main(String[] args) {
m1();
}
public static void m1() {
m2();
}
public static void m2() {
m3();
}
public static void m3() {
new FileInputStream("c:/abc.txt");
}
}
运行结果可想而知:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type FileNotFoundException
at p03.Exception.ThrowsText03.m3(ThrowsText03.java:20)
at p03.Exception.ThrowsText03.m2(ThrowsText03.java:16)
at p03.Exception.ThrowsText03.m1(ThrowsText03.java:12)
at p03.Exception.ThrowsText03.main(ThrowsText03.java:8)
那就用throws向上抛出异常吧。
import java.io.*;
public class ThrowsText03 {
public static void main(String[] args) {
m1();
}
public static void m1() {
m2();
}
public static void m2() {
m3();
}
public static void m3() throws Exception{
new FileInputStream("c:/abc.txt");
}
}
猜猜结果?
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type Exception
at p03.Exception.ThrowsText03.m2(ThrowsText03.java:16)
at p03.Exception.ThrowsText03.m1(ThrowsText03.java:12)
at p03.Exception.ThrowsText03.main(ThrowsText03.java:8)
仍然报错!只有无限的往上抛出编译才会通过:
import java.io.*;
public class ThrowsText03 {
public static void main(String[] args) throws Exception{
m1();
//上面的m1()方法出现了异常,向上抛出,给了JVM,JVM就会退出,下面这个代码不会执行
System.out.println("Hello World!");
}
public static void m1() throws Exception{
m2();
}
public static void m2() throws Exception{
m3();
}
public static void m3() throws Exception{
new FileInputStream("c:/abc.txt");
}
}
虽然解决了编译时的异常,但是“Hello World”语句并没有输出,说明在遇到异常的时候并没有解决 ,而是抛给了JVM,JVM碰到异常就退出了,无法执行“Hello World”语句!
Exception in thread "main" java.io.FileNotFoundException: c:\abc.txt (系统找不到指定的文件。)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:110)
at p03.Exception.ThrowsText03.m3(ThrowsText03.java:23)
at p03.Exception.ThrowsText03.m2(ThrowsText03.java:19)
at p03.Exception.ThrowsText03.m1(ThrowsText03.java:15)
at p03.Exception.ThrowsText03.main(ThrowsText03.java:8)
那么问题来了:throws真的是处理了异常吗?
不,它只是在推卸责任,把问题丢给上一级,并不会解决问题!建议大家碰见异常还是要用try…catch…比较好。
(3)try…catch…
try{
可能出现异常的代码
}catch(异常类型1 变量){
处理异常的代码;
}catch(异常类型2 变量){
处理异常的代码;
}....
举个例子:
FileInputStream fis = null;
try {
//JVM会自动创建一个FileNotFoundException类型的对象,将该对象的内存地址复制给catch语句块中的e变量。
fis = new FileInputStream("abc.txt");
//上面的代码出现异常,try语句块的代码不再继续执行,直接进入catch语句块执行
System.out.println("aaaaaa");
}catch(Exception e) {
System.out.println(e);
}
6、如何获取异常对象的具体信息?
有两种方法:getMessage()方法和printStackTrace()方法
getMessage()方法:
try {
FileInputStream fis = new FileInputStream("abc.txt");
}catch(Exception e) {
System.out.println(e.getMessage());
}
异常信息:
abc.txt (系统找不到指定的文件。)
printStackTrace()方法:
try {
FileInputStream fis = new FileInputStream("abc.txt");
}catch(Exception e) {
e.printStackTrace();
}
异常信息:
java.io.FileNotFoundException: abc.txt (系统找不到指定的文件。)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:110)
at p03.Exception.TryCatchText03.main(TryCatchText03.java:35)
7、finally语句块
finally语句块是一定会执行的,所以通常在程序中为了保证某
资源一定会释放,一般在finally语句块中释放资源。
//必须声明在外面
FileInputStream fis = null;
try {
fis = new FileInputStream("abc.txt");
System.out.println("aaaaaa");
}catch(FileNotFoundException e) {
e.printStackTrace();
}finally {
//避免空指针异常
if(fis!=null) {
try {
fis.close(); //.close()关闭并释放内存
}catch(IOException e) {
e.printStackTrace();
}
}
}
8、自定义无效名字异常
//自行创建异常
class CustomExceptionText extends Exception{ //编译时异常
//class CustomExceptionText extends RuntimeException{ //运行时异常
//定义异常一般提供两个构造方法
public CustomExceptionText() {
}
public CustomExceptionText(String msg) {
super(msg);
}
}
提供注册的方法:
class CustomException{
public void register(String name) throws Exception{
if(name.length() < 6) {
/**
//创建异常对象
CustomExceptionText e = new CustomExceptionText("用户名不能少于6位");
//手动抛出异常
throw e;
*/
//编译时异常需要程序员惊醒处理,自己手动抛出了异常,就不会再用try...catch..处理,用throws向上抛
throw new CustomExceptionText("用户名不能少于6位");
}
System.out.println("注册成功");
}
}
运行测试:
public class CustomText04{
public static void main(String[] args) {
String name = "jack";
CustomException c = new CustomException();
//继续用throws向上抛则无法解决问题,需要进行捕捉处理
try{
c.register(name);
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
运行结果:
用户名不能少于6位
9、方法的重写与异常:
重写的方法不能比被重写的方法抛出更宽泛的异常
class A {
public void m1() {}
}
class B extends A{
//子类永远无法抛出比父类更多的异常。
public void m1() throws Exception{}
}
程序报错,编译无法通过
class A {
public void m1() IOException{}
}
class B extends A{
//子类永远无法抛出比父类更高级的异常。
public void m1() throws Exception{}
}