Java自学-异常机制

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{}
	
}
发布了3 篇原创文章 · 获赞 0 · 访问量 18

猜你喜欢

转载自blog.csdn.net/weixin_44317777/article/details/105279646