JavaSE_day16:异常处理

1.异常

1.1 异常的体系结构

 * java.lang.Throwable
 * 		|-----java.lang.Error:一般不编写针对性的代码进行处理。
 * 		|-----java.lang.Exception:可以进行异常的处理
 * 			|------编译时异常(checked)
 * 					|-----IOException
 * 						|-----FileNotFoundException
 * 					|-----ClassNotFoundException
 * 			|------运行时异常(unchecked,RuntimeException)
 * 					|-----NullPointerException
 * 					|-----ArrayIndexOutOfBoundsException
 * 					|-----ClassCastException
 * 					|-----NumberFormatException
 * 					|-----InputMismatchException
 * 					|-----ArithmeticException

1.2 异常种类

编译时异常:执行javac.exe命令时,可能出现的异常,应考虑使用异常处理
运行时异常:执行java.exe命令时,出现的异常,可不考虑异常处理

1.3 常见的异常类型

* 面试题:常见的异常都有哪些?举例说明
 */
public class ExceptionTest {
	// ******************以下是编译时异常***************************
	@Test
	public void test7() {
//		File file = new File("hello.txt");
//		FileInputStream fis = new FileInputStream(file);
//
//		int data = fis.read();
//		while (data != -1) {
//			System.out.print((char) data);
//			data = fis.read();
//		}
//
//		fis.close();

	}

	// ******************以下是运行时异常***************************
	// NullPointerException
	// 空指针异常
	@Test
	public void test1() {
		String str = "abc";
		str = null;
		System.out.println(str.charAt(0));
	}

	// IndexOutOfBoundsException/StringIndexOutOfBoundsException
	// 越界异常
	@Test
	public void test2() {
		String str = "abc";
		System.out.println(str.charAt(3));
	}

	// ClassCastException
	// 类型转换异常
	@Test
	public void test3() {
		Object obj = new Date();
		String str = (String) obj;
	}

	// NumberFormatException
	// 数字格式异常
	@Test
	public void test4() {
		String str = "123";
		str = "abc";
		int num = Integer.parseInt(str);
	}

	// InputMismatchException
	// 输入类型不匹配异常
	@Test
	public void test5() {
		Scanner scanner = new Scanner(System.in);
		// 当输入字符时,会报错
		int score = scanner.nextInt();
		System.out.println(score);

		scanner.close();
	}

	// ArithmeticException
	// 算术运算异常
	@Test
	public void test6() {
		int a = 10;
		int b = 0;
		System.out.println(a / b);
	}
}

2.异常的处理

2.1 异常处理的抓抛模型

过程一:“抛”:程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象,并将此对象抛出。一旦抛出对象以后,其后的代码就不再执行。

  • 关于异常对象的产生:
    ① 系统自动生成的异常对象
    ② 手动的生成一个异常对象,并抛出(throw

过程二:“抓”:可以理解为异常的处理方式:① try-catch-finallythrows

2.2 try-catch-finally

运行时异常的使用:

@Test
public void test1() {
	try {
		int a = 10;
		int b = 0;
		System.out.println(a / b);

	} catch (ArithmeticException e) {
		e.printStackTrace();
		//catch里面的异常
		int[] arr = new int[10];
		System.out.println(arr[10]);

	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 一定会执行的代码
		System.out.println("1--我可以执行~~");
	}
	// catch语句执行后,假如catch没有异常后,以下语句都会执行
	//此代码运行不会运行以下语句,上面catch里面有异常
	System.out.println("2--我可以执行~~");
}
@Test
public void testMethod() {
	int num = method();
	System.out.println(num);//输出是 3
}

public int method() {

	try {
		int[] arr = new int[10];
		System.out.println(arr[10]);
		return 1;
	} catch (ArrayIndexOutOfBoundsException e) {
		e.printStackTrace();
		return 2;
	} finally {
		System.out.println("我一定会被执行");
		return 3;
	}
}

编译时异常的使用:

体会1:使用try-catch-finally处理编译时异常,是得程序在编译时就不再报错,但是运行时仍可能报错。相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
体会2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。针对于编译时异常,我们说一定要考虑异常的处理。

@Test
public void test2() {
	FileInputStream fis = null;
	try {
		File file = new File("hello1.txt");
		fis = new FileInputStream(file);

		int data = fis.read();
		while (data != -1) {
			System.out.print((char) data);
			data = fis.read();
		}
	//1.先子类
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {//2.后父类
		e.printStackTrace();
	} finally {
		try {
			if (fis != null)
				fis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

2.3 小结说明

  • finally是可选的,其一定会被执行,即使有returncatch里面再次异常
  • 像数据库连接、输入输出流、网络编程Socket等资源,释放资源时要使用finally
  • 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配
  • 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的try-catch结构(在没写finally的情况,继续执行其后的代码)
  • catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面;否则,报错
  • 常用的异常对象处理的方式: ① getMessage()printStackTrace()
  • try结构中声明的变量,再出了try结构以后,就不能再被调用
  • try-catch-finally结构可以嵌套

2.4 throws + 异常类型

"throws + 异常类型"写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后续的代码,就不再执行!

体会:try-catch-finally:真正的将异常给处理掉了。throws的方式只是将异常抛给了方法的调用者。 并没有真正将异常处理掉。

public class ExceptionTest2 {
	public static void main(String[] args){
		try{
			method2();	
		}catch(IOException e){
			e.printStackTrace();
		}
		method3();
		
	}
	
	public static void method3(){
		try {
			method2();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//IOException包括了FileNotFoundException
	public static void method2() throws IOException{
		method1();
	}
		
	public static void method1() throws FileNotFoundException,IOException{
		File file = new File("hello1.txt");
		FileInputStream fis = new FileInputStream(file);
		
		int data = fis.read();
		while(data != -1){
			System.out.print((char)data);
			data = fis.read();
		}
		fis.close();
		//不会再执行
		System.out.println("hahaha!");
	}
}

体会开发中应该如何选择两种处理方式?

  • 如果父类中被重写的方法没throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中异常,必须使用try-catch-finally方式处理。
  • 执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。

3. 手动抛出异常对象

public class StudentTest {
	public static void main(String[] args) {
		try {
			Student s = new Student();
			s.regist(-1001);
			System.out.println(s);
		} catch (Exception e) {
//			e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}
}

class Student{
	private int id;
	public void regist(int id) throws Exception {
		if(id > 0){
			this.id = id;
		}else{
//			System.out.println("您输入的数据非法!");
			//手动抛出异常对象
//			throw new RuntimeException("您输入的数据非法!");
//			throw new Exception("您输入的数据非法!");
			//自定义异常类
			throw new MyException("不能输入负数");
			//错误的
//			throw new String("不能输入负数");
		}
		
	}
	@Override
	public String toString() {
		return "Student [id=" + id + "]";
	}
}

4. 自定义异常类

如何自定义异常类?
1.继承于现的异常结构:RuntimeExceptionException
2.提供全局常量:serialVersionUID (模仿已有的异常类的ID)
3.提供重载的构造器

public class MyException extends Exception{
	//模仿已有的异常类的ID
	static final long serialVersionUID = -7034897193246939L;
	public MyException(){
		
	}
	public MyException(String msg){
		super(msg);
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值