JAVA进阶版:异常机制处理

(1)异常机制的2种方式:throws, try…catch…

package 异常机制处理;
/**
 * 处理异常有两种方式:
 * 1.声明向上抛出 throws
 * 2.捕捉 try....catch....
 * 
 * 以下程序演示第一种方式:声明抛出,在方法声明的位置上使用throws关键字向上抛出异常
 * */
import java.io.*;
public class ExceptionTest01 {

	//public static void main(String[] args) throws FileNotFoundException {
	//public static void main(String[] args) throws IOException {
	public static void main(String[] args) throws Exception {	
		//创建文件输入流,读取文件
		//思考:java编译器是如何知道以下的代码执行过程中可能出现异常。
		//java编译器是如何知道这个异常发生的几率较高的呢?
		//java编译器不是那么智能,因为FileInputStream这个构造方法在声明的位置上使用了throws FileNotFoundException;
		FileInputStream fils=new FileInputStream("c:/ab.txt");
	}

}

(2) 深入throws

package 异常机制处理;
/**
 * 深入throws
 * 子类与父类继承的关系或者说包含的关系 :FileNotFoundException < IOException < Exception
 * */
import java.io.*;//导入其他包调用
public class ExceptionTest02 {

	public static void main(String[] args) throws Exception {//main抛给jvm虚拟机
		
		/*m1();
		//使用throws处理异常不是真正处理异常而是推卸责任。虽然编译通过,但是hello运行不出来。
		//谁调用的就抛给谁(向上抛)
		//上面的m1方法如果出现了异常,因为采用的是上抛,给了JVM,JVM遇到这个异常就会退出JVM,下面的这个代码不会执行。
		System.out.println("hello");//Exception in thread "main" java.io.FileNotFoundException: c:\ab.txt (系统找不到指定的文件。)
	*/
		
		//真正处理运用 try..catch...,就可以输出System.out.println("hello")
		try {
			m1();
		}catch(Exception e) {}
		System.out.println("hello");//hello
	}
	
	public static void m1() throws IOException {
		m2();
	}
	
    public static void m2() throws FileNotFoundException{
		m3();
	}
    
    public static void m3() throws FileNotFoundException{
		new FileInputStream("c:/ab.txt");//FileInputStream构造方法声明位置上使用throws(向上抛)
	}
}

(3) 方式2:try…catch

  • 1.catch语句块可以写多个。
  • 2.但是catch要从上到下,必须从小类型异常到大类型异常进行捕捉。
    ----(从小到大)FileNotFoundException < IOException < Exception
  • 3.try… catch…中最多执行一个catch语句块(其余的catch语句块不执行,但是必须写,为了处理其他异常),执行结束后try…catch…就结束了。
  • 4.try语句块无异常,不执行catch 语句,但一般写catch语句,以防出现异常。
package 异常机制处理;
/**
 * 处理异常的第二种方式:捕捉 ...try...catch...
 * 语法:
 * try{可能出现的异常代码;
 * } catch (异常类型1 变量) {
 *           处理异常代码;
 * } catch (异常类型2 变量) {
 *           处理异常代码;
 * }.....
 * 
 * */
import java.io.*;
public class ExceptionTest03 {

	public static void main(String[] args) {
		
		//以下代码编译无法通过,因为FileNotFoundException没有处理
		/*try {
			//FileNotFoundException
			FileInputStream fis=new FileInputStream("c:/ba.txt");
		}catch(ArithmeticException e) {//捕获的异常是算术异常,不是文件读取异常
		}
	*/
		/*  //编译通过
		try {
			//FileNotFoundException
			FileInputStream fis=new FileInputStream("c:/ba.txt");
		}catch(FileNotFoundException e) {//捕获文件读取异常
		}
		*/
		
		/*//以下程序编译无法通过,因为还有更多IOException没有处理
		try {
			//FileNotFoundException
			FileInputStream fis=new FileInputStream("c:/ba.txt");
			
			fis.read();//IOException异常
			
		}catch(FileNotFoundException e) {
		}
		*/
		
		//程序编译通过
		/*try {
			//FileNotFoundException
			FileInputStream fis=new FileInputStream("c:/ba.txt");
			
			fis.read();
			
		}catch(FileNotFoundException e) {
		}catch(IOException e) {
		}*/
		
		//编译通过,IOException包含FileNotFoundException
		/*try {
			//FileNotFoundException
			FileInputStream fis=new FileInputStream("c:/ba.txt");
			
			fis.read();
			
		}catch(IOException e) {
		}
		*/
		
		//编译无法通过,catch语句可以写多个,但必须从上到下,从小到大捕捉
		/*try {
			//FileNotFoundException
			FileInputStream fis=new FileInputStream("c:/ba.txt");
			
			fis.read();
		//两者顺序反过来了,catch从大到小编译不通过,	
		}catch(IOException e) {
		}catch(FileNotFoundException e) {
		}*/
}
}

(4) 深入try…catch…

注意:
(1)出现异常的语句,之后的语句不再执行(包括异常语句),从上到下执行第一个异常catch语句块;
(2)其余catch语句块不执行(处理其他异常句),但是必须写,否则其他异常句没有处理,编译不通过。

package 异常机制处理;
/**
 * 结果:读取的文件不存在
 *        ABC
 * */
import java.io.*;
public class ExceptionTest04 {

	//编译无法通过
	//IOException没有处理
	/*public static void main(String[] args) throws FileNotFoundException {
		FileInputStream fis=new FileInputStream("abc");
		fis.read();
	}*/

	//编译通过
	/*public static void main(String[] args) throws FileNotFoundException,IOException{
		FileInputStream fis=new FileInputStream("abc");
		fis.read();
	}*/
	
	//编译通过
	/*public static void main(String[] args) throws IOException{
		FileInputStream fis=new FileInputStream("abc");
		fis.read();
	}*/
	
	public static void main(String[] args){
		try{
			
			//程序执行到此处发生了FileNotFoundException类型的异常。
			//jvm会自动创建一个FileNotFoundException类型的对象,将该对象的内存地址赋值给catch语句块中的e变量
			FileInputStream fis=new FileInputStream("abc");
			
			/*上面的代码出现了异常,try语句块的代码不再继续执行(即不执行System.out.println("TTT");语句和fis.read();这个异常),
			 * 直接进入catch语句块中执行,从上往下执行第一个catch语句块
			 * try... catch...中最多执行一个catch语句块,执行结束后try...catch..就结束了
			*/
			System.out.println("TTT");
			
			fis.read();
			
			}catch(FileNotFoundException e) {//e内存地址指向堆中的那个对象是“FileNotFoundException类型的”事件
				System.out.println("读取的文件不存在");
			
			}catch(IOException e){//这个catch语句块虽然不执行,但是不能删除,是处理fis.read();,否则报错
				System.out.println("其他IO异常");
			}
		
		System.out.println("ABC");
	}
}

(5) getMessage和printStackTrace打印异常语句

package 异常机制处理;
/**
 * 关于getMessage和printStackTrace方法的应用。
 * */
import java.io.*;
public class ExceptionTest05 {

	public static void main(String[] args) {
		try {
		
			FileInputStream fis=new FileInputStream("c:/ab.txt");
			
		}catch(FileNotFoundException e) {
			//打印异常堆栈信息
			//一般情况下都会使用该方法去调试程序
			e.printStackTrace();
			
			/*
			 * java.io.FileNotFoundException: c:\ab.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 异常机制处理.ExceptionTest05.main(ExceptionTest05.java:11)
			 * */
			String msg =e.getMessage();//这种调用方法比上面的printStackTrace方法简略
			System.out.println(msg);//c:\ab.txt (系统找不到指定的文件。)
		}
		//这段代码会执行
		System.out.println("ABC");
	}
	
}

(6) try…catch…finally

package 异常机制处理;
/**
 * 关于finally语句块
 * 1.finally语句块可以直接和try语句块联用。try....finally....
 * 2.try...catch...finally也可以
 * 3.在finally语句块中的代码是一定会执行的
 * */
import java.io.*;
public class ExceptionTest06 {

	public static void main(String[] args) throws Exception {
		/*try {
			//此处不是异常语句
			System.out.println("ABC");//ABC
			return;
		}finally {
			System.out.println("Tset");//Test
		} */
		
		/*try {
			FileInputStream fis=new FileInputStream("Test.java");
			//上面语句块出现异常,下面不会执行
			System.out.println("Hello");
		}finally {
			//会执行
			System.out.println("AAAA");
		}*/
		
		//只要在执行finally语句块之前退出了JVM,则finally语句块不会执行。
		try {
			//退出JVM
			System.exit(0);
		}finally {
			//不会执行
			System.out.println("finally");
		}
	}

}

(7) 深入finally语句块

package 异常机制处理;
/**
 * 结果:m1的i=11
*        10
 * 深入finally语句块
 * */
public class ExceptionTest07 {

	public static void main(String[] args) {
		int i=m1();
		System.out.println(i);//10
	}
	
	public static int m1() {
		int i=10;
		try {
			return i;
		}finally {
			i++;
			System.out.println("m1的i="+i);//11
		}
		
		//m1方法的执行原理
		/*public static int m1() {
			int i=10;
			try {
				int temp=i;
				return temp;
			}
		
			}finally {
				i++;
				System.out.println("m1的i="+i);//11
			}*/
	}
}

(8) finally语句块释放资源

package 异常机制处理;
/**
 * finally语句块一定会执行,所以通常在程序中为了保证某资源一定会释放,所以一般在finally语句块中释放资源
 * */
import java.io.*;
public class ExceptionTest08 {

	public static void main(String[] args) {
		//必须在外边声明,才能释放流
		FileInputStream fis=null;
		try{//语句正常,能找到文件,所以catch处理异常不执行
			 
			fis=new FileInputStream("ExceptionTest08.java");
		
			//try语句块无异常,不执行catch 语句
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}finally {
			//为了保证资源一定会释放
			if(fis!=null) {
				try {
					fis.close();//这是个异常,故下面catch(IOException e)处理
				}catch(IOException e) {
				e.printStackTrace();//输出异常
				}
			}
		}
	}
}

(9) 编译异常和运行异常

package 异常机制处理;
/**
*自定义“无效名字异常”。
*1.编译时异常,直接继承Exception
*2.运行时异常,直接继承RuntimeException
*/
public class ExceptionTest09 extends Exception {//编译时异常
//public class ExceptionTest09 extends RuntimeException {//运行时异常
	
	//定义异常一般提供两个构造方法
	public ExceptionTest09() {}
	
	public ExceptionTest09(String msg) {
		super (msg);
	}
}

(10) 重写的方法不能比被重写的方法抛出更宽泛的异常

package 异常机制处理;
/*
 * 重写的方法不能比被重写的方法抛出更宽泛的异常
 * **/
import java.io.*;

/*
public class ExceptionTest10 {
	public void m1() {}
}

class B extends ExceptionTest10 {
	//子类永远无法抛出比父类更多的异常
	public void m1() throws Exception()
}
*/

class ExceptionTest10{
	//public void m1() throws FileNotFoundException{}
	public void m1() throws IOException{}
}

class B extends ExceptionTest10{
	//public void m1() throws IOException{}
	public void m1() throws FileNotFoundException{}
}

(11) 异常例子

package 异常机制处理;
/**
 * 模拟注册
 * */
public class Test09 {
	
	public static void main(String[] args) {
		//假如用户提供的用户名如下:
		//String username="jack";//这个有异常,结果是用户名的长度不能少于6位
		String a="ajsjsaksja";//这个就是没有异常,结果是注册成功
		//注册
		CustomerService09 cs=new CustomerService09();
		try {
			//cs.register(username);
			cs.register(a);
			}catch(ExceptionTest09 e) {
				System.out.println(e.getMessage());
			}
		
	}

}
package 异常机制处理;
//顾客相关的业务
public class CustomerService09 {
	//对外提供一个注册的方法
	public void register(String name) throws ExceptionTest09  {//手动创建的异常,想让外面程序知道,用throws
		//完成注册
		if(name.length()<6) {
			//异常
			//创建异常对象
			//ExceptionTest09 e=new ExceptionTest09("用户名的长度不能少于6位");
			
			//手动抛出异常
			//throw e;
			
			//连起来写,编译异常必须进行处理,throws或try..catch..
			throw new  ExceptionTest09("用户名的长度不能少于6位");
		}
		//如果代码能执行到此处,证明用户名是合法的
		System.out.println("注册成功");
	}
}
发布了71 篇原创文章 · 获赞 10 · 访问量 3422

猜你喜欢

转载自blog.csdn.net/JH39456194/article/details/104070752