异常知识点整理(Throwable,throws,throw ,finally ,自定义异常)

一、异常

异常概述:异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。简单来说就是程序出现了不正常的情况。异常本质就是Java当中对可能出现的问题进行描述的一种对象体现。

常见异常:
除数不能为0异常(ArithmeticException)
空指针异常(NullPointException)
数组越界异常(ArrayIndexOutOfBoundsException)
类型转换异常(ClassCastException)
Error:称为错误,由Java虚拟机生成并抛出,程序对其不做处理。

异常分类

  • Exception:所有异常类的父类,其子类对应了各种各样可能出现的异常事件,一般需要用户显示的声明或捕获。

  • RuntimeException:运行时期异常,又称为非受检异常,RuntimeException及其所有子类都是运行时期异常。

  • 编译时期异常:不是继承自RuntimeException的Exception的子类都成为编译时期异常。

处理异常的目的:
并不是为了修复程序的错误,而是就算程序出现了错误,也能够让程序继续执行

虚拟机的处理方式:
把异常的名称,异常出现的位置,异常原因,等信息输出打印在控制台,并同时将 程序停止执行。

如果我们不做任何处理,异常将会交由虚拟机来处理,JVM处理异常的方式不能够满足我们开发的需求,那么我们需要自己处理异常

我们自己处理异常的方式:
1、try…catch…finally
2、throws抛出异常

单个异常的处理
try…catch…finally的处理格式:
异常处理的格式:
try{
//放置程序可能出现问题的代码
}catch(异常类 异常名){
//这里放置异常处理的代码
} finally{
//释放资源
}
注意:

  • 1.try块的代码越少越好
  • 2.try块中一旦发生异常,那么try块中发生异常后面所有的代码都不会被执行
  • 3.多个catch块只会执行一个
  • 4.Exception接受异常必须放在异常的最后面,满足先子类后父类

异常的执行流程:

  • 1.程序执行到错误行,系统会创建一个异常对象,并且抛给我们
  • ArithmeticException exp = new ArithmeticException("/by zero");
  • throw exp;
  • 2.程序进入catch块进行逐个匹配
  • 匹配成功,程序执行catch块代码
  • ArithmeticException ae = exp;
  • Exception e = exp;
  • 匹配失败,交给jvm处理

处理异常的标准方式:

  • 1.能够显示处理的尽量显示处理,提高程序的可读性
  • 2.但是一定要在异常处理的最后加上 父类Exception处理

二、Throwable 类

Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

成员方法
public String getMessage():返回此 throwable 的详细消息字符串
public String toString():获取异常类名和异常信息。
public void printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。
public void printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅

public class ExceptionDemo {
	public static void main(String[] args) throws FileNotFoundException {
		Throwable throwable = new NullPointerException();
		Throwable throwable = new ArithmeticException("除数不能为0");
		String message = throwable.getMessage();
		System.out.println(message);
		
		
		System.out.println(throwable.toString()); // java.lang.ArithmeticException: 除数不能为0 
		
		 public void printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。
		throwable.printStackTrace(); 
		
		 public void printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。 
		
		throwable.printStackTrace(new PrintWriter("a.txt"));
		StackTraceElement[] stackTrace = throwable.getStackTrace();
		for (int i = 0; i < stackTrace.length; i++) {
			System.out.println(stackTrace[i].getMethodName() + "|" + stackTrace[i].getClassName() + "|" + stackTrace[i].getLineNumber() + "|" + stackTrace[i].getFileName()) ;
		}
		
		
		
	}
}

1.Throws关键字

Throws关键字概述
在定义一个方法的时候可以使用throws关键字声明,使用throws声明的方法表示此方法不处理异常,而交给方法的调用者进行处理。

throws使用格式
[修饰符] 返回值类型 方法名(参数列表) [throws 异常类1,异常类2…]{
}

注意:
1、如果一个方法声明的是编译时期异常,则在调用这个方法之处必须处置这个异常(谁调用该有问题的方法谁处理)。
2、重写一个方法时,它所声明的异常范围不能被扩大。

public class ExceptionDemo {
	public static void main(String[] args) {
		try {
			calc();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try {
			method();
		} catch (ParseException e) {
			
			e.printStackTrace();
		}
		System.out.println("00000000000000000");
		
	}
	
	public static int calc() throws ArithmeticException{
		int a = 10;
		int b = 0;
		int result = a/b;
		return result;
	}
	
	public static void method() throws ParseException{
		String s = "2018-04-28";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM/dd");
		sdf.parse(s);
	}
}

class Father{
	public void show() throws Exception{
	}
}

class Son extends Father{
	@Override
	public void show() throws NullPointerException,ArithmeticException,ClassCastException {
	}
}

Throw关键字

在方法代码中主动抛出一个异常。如果方法代码中自行抛出的异常是编译时期异常,则这个方法要用throw关键字声明这个异常。

格式:

  • throw 异常对象;
  • 谁调用就将对象抛给谁
  • 当抛出的是编译时异常的时候,必须要在方法体上声明异常
  • 当时运行时异常的时候,可以不用声明,但是建议声明

Throws和Throw的区别

  • 1.throws用在方法声明后面,跟的是异常类名,throw用在方法体内,跟的是异常对象名。
  • 2.throws可以跟多个异常类名,用逗号隔开,throw只能抛出一个异常对象名。
  • 3.throws表示抛出异常,由该方法的调用者来处理,throw表示抛出异常,由方法体内的语句处理。
  • 4.throws表示出现异常的一种可能性,并不一定会发生这些异常,throw则是抛出了异常,执行throw则一定抛出了某种异常。
public class ExceptionDemo {
	public static void main(String[] args) {
		String s = new String(new byte[] {11,22,33,44}, -1, 3);
		System.out.println(s);
		try {
			calc();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("go on");
	}

	private static void calc() throws CloneNotSupportedException {
		int a = 10;
		int b = 0;
		// 方式一处理异常:
//		if (b != 0) {
//			System.out.println(a / b);
//		}
		
		// 方式二处理异常:
		if (b == 0) {
			throw new CloneNotSupportedException("除数不能为0");
		}
		System.out.println(a / b);
		
	}
}

finally关键字

1.finally修饰的代码块一定会被执行,除非在执行到finally之前程序异常退出或者调用了系统退出的方法。如:System.exit(0);Runtime.getRuntime().exit(0);
2.finally用于释放资源,比如关闭IO流的输入输出对象,数据库连接对象等。

public class FinallyTest {
	public static void main(String[] args) {

		System.out.println(test());
	}

	public static int test() {
		int x = 1;
		try {
			x++;
			return x;
		} finally {
			++x;
			System.out.println(x); 
		}
	}
}

finalize()方法,finally关键字,final关键字的区别

1.finalize()方法

  • 当垃圾回收器确定不存在对该对象的更多引用时,
  • 由对象的垃圾回收器调用此方法。用于垃圾回收,但是什么时候回收不确定。

2.final

  • final修饰的变量表示常量,不能够被二次赋值
  • final修饰的类不能够被继承
  • final修饰的方法不能够被子类重写

3.finally

  • 一般用来释放内存资源(io流的端口,网络的端口,数据库的连接断开等等)

三、自定义异常

自定义异常的步骤

  • 1.创建一个异常类继承 Exception或者RuntimeException
  • 2.在自定义异常类中书写构造方法即可

a.无参构造
b.带错误信息的构造方法

**举例:**自定义一个异常,要求考试成绩必须在0-100之间,如果不在这个范围内,抛出异常。自定义异常:继承自Exception

public class ExceptionDemo {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("请输入一个分数:");
		double score = input.nextDouble();
		Teacher teacher = new Teacher();
		try {
			System.out.println(teacher.isBetween0To100(score) ? "分数合法" : "分数不合法");
		} catch (ScoreException e) {
//			e.printStackTrace();
			System.err.println(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			input.close();
		}
		System.out.println("分数批改完毕!");
				
	}
}

class ScoreException extends Exception{
	
	public ScoreException(){}
	
	public ScoreException(String message) {
		super(message);
	}
}

class Teacher{
	
	public boolean isBetween0To100(double score) throws ScoreException{
		if (score > 100 || score < 0) {
			throw new ScoreException("分数必须在0-100分之间!!!");
		}
		return true;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值