Java基础:异常处理Exception

目录

1.异常概述与异常体系结构

2.常见异常

​​​编译时异常(checked)

运行时异常(unchecked,RuntimeException)

3.异常处理机制一:try-catch-finally

try-catch:

finally:

体会:

4.异常处理机制二:throws+异常类型

throws:

体会:

5.手动抛出异常:throw

6.用户自定义异常类

如何自定义异常类?

7.面试题:throw 跟 throws的区别


1.异常概述与异常体系结构

        在开发过程中,即便把代码写的尽善尽美,但在系统运行过程中仍然会遇到一些问题。很多问题不是靠代码就能够避免的。比如:用户输入数据的格式、读取的文件是否存在、网络是否通畅等等。

  • 异常:在Java中,将程序执行中发生的不正常情况称为“异常”。
  • Java程序在执行过程所发生的异常事件可分为两类:
    • Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError(栈溢出)OOM(堆溢出)。一般不编写针对性的代码进行处理。
    • Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以用针对性的代码进行处理。例如:
      • 空指针访问
      • 试图读取不存在的文件
      • 网络连接中断
      • 数组下标越界
  • 解决方法
    • 第一种:遇到错误就终止程序运行。
    • 第二种:在编写程序时,考虑到错误的检测、错误消息的提示,以及错误的处理。
  • 捕获最理想的是在编译期间,但又的错误只有在运行时才会发生。比如:除数为0,数组下标越界等。
    • 分类:编译时异常运行时异常

watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfMzM0OTE2NTE=,size_16,color_FFFFFF,t_70,g_se,x_16

 

2.常见异常

  • ​​​编译时异常(checked)

    • IOException
      • FileNotFoundException
    • ClassNotFoundException
  • 运行时异常(unchecked,RuntimeException)

    • NullPointerException 空指针异常
    • ArrayIndexOutOfBoundsException 数组下标越界
    • ClassCastException 类型转换异常
    • NumberFormatException 数字格式化异常
    • InputMismatchException
    • Arithmeticexception
import java.util.Date;
import java.util.Scanner;

import org.junit.Test;

public class ExceptionTest {

	// NullPointerException 空指针异常
	@Test
	public void test1() {
		String str = "abc";
		str = null;
		System.out.println(str.charAt(0));

	}

	// ArrayIndexOutOfBoundsException 数组下标越界
	@Test
	public void test2() {
		int[] arr = new int[3];
		System.out.println(arr[3]);

	}

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

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

	// InputMismatchException 输入不匹配异常
	@Test
	public void test5() {
		Scanner in = new Scanner(System.in);
		int score = in.nextInt();
		// 输入字符串
		System.out.println(score);

	}

	// Arithmeticexception 算数异常
	@Test
	public void test6() {
		int a = 4;
		int b = 0;
		// 输入字符串
		System.out.println(a / b);

	}
}

3.异常处理机制一:try-catch-finally

try {
	//可能出现异常的代码
	} catch (异常类型1 变量1) {
	//处理异常的方式1
    } catch (异常类型2 变量2) {
	//处理异常的方式2
    } catch (异常类型3 变量3) {
	//处理异常的方式3
    }
finally {
    //一定会执行的代码
}

try-catch

  1. 使用try将可能出现异常的代码包装起来,在执行过程中,一单出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。
  2. 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出try-catch结构(在没有写finally的情况下),继续执行其后的代码。
  3. catch中的异常类型如果没有子父类关系,则声明的上下顺序无所谓;如果存在子父类关系,则要求子类一定在上面,否则报错。
  4. 常用的异常对象处理的方式:1.String getMessage() 2.printStackTrace()
  5. 在try结构中声明的变量,在出了try结构之后,不能再被调用。

finally

  1. finally是可选的。
  2. finally 中声明的是一定会被执行的代码。即使catch中又出现异常、try中有return、catch中有return的情况。且在执行return、throw前,先执行finally
  3. 像数据库连接、输入输出、网络编程Sokect等资源,JVM是不能自动回收的,我们需要自己手动进行资源的释放,此时需要将资源释放声明在finally里。

面试题:final、finally、finalize三者的区别

 finalfinallyfinalize
区别

最终。

修饰类不能被继承

修饰方法不能被重写

修饰属性表示常量,不能被重新赋值

处理异常时一定会运行的部分。

是Object里面的一个方法。

当一个堆空间中的对象没有被栈空间变量指向的时候,这个对象会等待被java回收。

体会

  1. 使用try-catch-finally结构处理编译时异常,使得程序在编译时就不再报错,但运行时仍可能报错。相当于使用try-catch-finally讲一个编译时可能出现的异常,延迟到运行时才出现。
  2. 针对编译时异常,一定要考虑异常的处理。但由于运行时异常比较常见,所以通常不对运行时异常编写try-catch-finally
package com.ch.exceptionDemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.junit.Test;

public class TryCatchExceptionTest {
	@Test
	public void test1() {
		FileInputStream fis = null;
		try {
			File file = new File("hello.txt");
			fis = new FileInputStream(file);

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

	}
}

 

4.异常处理机制二:throws+异常类型

throws:

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

体会

  • try-catch-finally:真正将异常处理掉。
  • throws:将异常抛给方法的调用者,并没有真正的把异常处理掉。
package com.ch.exceptionDemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ThrowsExceptionTest {
		

	public void method2() throws IOException {
		method();
	}

	public void method() throws FileNotFoundException, IOException {
		FileInputStream fis = null;
		File file = new File("hello.txt");
		fis = new FileInputStream(file);
		int data = fis.read();
		while (data != -1) {
			System.out.print((char) data);
			data = fis.read();

		}
	}
}

throws方法重写

  1. 子类重写的方法抛出的异常<=被重写的方法抛出的异常。
package com.ch.exceptionDemo;

import java.io.FileNotFoundException;
import java.io.IOException;

public class OverrideTest {
	public static void main(String[] args) {
		OverrideTest overridetest = new OverrideTest();
		SubClass subclass = new SubClass();
		overridetest.show(subclass);
	}

	public void show(SuperClass s) {
		try {
			s.method();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class SuperClass {
	public void method() throws IOException {

	}

}

class SubClass extends SuperClass {

	@Override
	public void method() throws FileNotFoundException {

	}

}

 

实际中选择:

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

 

5.手动抛出异常:throw

 


public class ThrowTest {

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

}

class Student {
	private int id;

	public void regist(int id) throws Exception {
		if (id > 0) {
			this.id = id;
		} else {
			// System.out.println("输入id有误");
			// 手动抛出异常
			// throw new RuntimeException("输入id有误");
			throw new Exception("输入id有误");
		}
	}

	@Override
	public String toString() {
		return "Student [id=" + id + "]";
	}

}

 

6.用户自定义异常类

如何自定义异常类?

  1. 继承于现有的异常结构:RuntimeException(运行时异常,可以不考虑处理)、Exception(考虑处理)
  2. 提供全局常量:serialVersionUID
  3. 提供重载的构造器。

 

7.面试题:throw 跟 throws的区别

 

 throwthrows
阶段异常的生成阶段(抛)异常的处理方式(抓)
内容手动抛出异常对象声明方法可能要抛出的异常类,将异常抛给方法的调用者,让调用者去具体处理。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值