Java基础—异常

本文介绍了Java异常处理机制,包括异常的分类、运行时异常与编译时异常的区别、异常的处理方式(try-catch-finally、throws)、自定义异常以及异常对象的抛出方式。通过学习,能理解Java中异常处理的关键字及其应用。

Java异常处理


1.异常

  • 在Java语言中,将程序执行中发生的不正常情况称为“异常”

2.为什么会有异常处理?

为了避免中断程序的执行流程,Java采用异常处理机制,将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁,并易于维护。

3.异常的体系结构

在这里插入图片描述

异常的根类:Throwable ,其子类有

  • 1)Error: JVM无法解决的严重问题(JVM系统内部错误、资源耗尽等严重情况)

  • 2)Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理

4.异常的分类

1.运行时异常:

  • 是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。

2.编译时异常:

  • 是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求java程序必须捕获或声明所有编译时异常。

分类:

  • 1)运行时异常(非受检异常):RuntimeException

    • NullPointerException
    • ClassCastException
    • ArrayIndexOutOfBoundsException
    • ArithmeticException
    • ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常
  • 2)编译时异常(受检异常):除运行时异常外的所有异常

    • IOException:如 FileNotFoundException
    • ClassNotFoundException:反射Class.forName(全类名)时,全类名不存在

5.为什么会有运行时异常,不用抛出?它如何自己捕获?

1.RuntimeException运行时异常:

  • 能够编译通过的异常( 但运行时会发生异常,会使程序运行终止 )
  • 运行时异常即使没有使用try和catch捕获,JVM自己也能捕获

2.非运行时异常:

  • 在编译的过程中, Java检测到某段代码[可能]会出现怎样的问题, 需要我们对程序进行预处理,如果不处理, 编译就不允许通过;
  • 也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常,否则会编译错误

问题:捕获和不捕获异常,程序的运行有什么不同

不捕获异常时的情况:

  • RuntimeException类及其子类,这些类的异常的特点是:
    即使没有使用try和catch捕获,Java自己也能捕获,并且编译通过 ( 但运行时会发生异常使得程序运行终止 )。
  • 如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则编译错误。也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常

6.受检异常的处理方式

1.try-catch-finally

1)try{…}语句块:选定捕获异常的范围

2)catch(Exceptiontype e) 方法:
1. 友情提示
2. 获取异常信息 e.getMessage() ——返回值 String 类型
3. 获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void e.printStackTrace();

3)finally:最终被执行的区域 不管遇到return/break/continue,其都会执行
用于关闭一些资源

注意:

  • System.exit(0);系统退出时,finally不执行
  • try异常处理代码块,如果异常被catch处理,则程序依旧会继续执行
try{
	......	//可能产生异常的代码
}
catch( ExceptionName1 e ){
	......	//当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e ){
...... 	//当产生ExceptionName2型异常时的处置措施
}  
[ finally{
......	 //无论是否发生异常,都无条件执行的语句
		}  ]

catch (Exceptiontype e):

  • 如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。
  • 比如:可以用ArithmeticException类作为参数的地方,就可以用RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException(catch中的语句将不会执行)。

面试题: final finalize finally 的区别

1)final 修饰符:

  • 可以修饰变量(不可变)、方法(不可重写)、类(不可被继承)

2)finalize 方法:Object的成员方法

  • 当垃圾对象被回收时,会默认通过垃圾收集器调用被回收对象的finalize方法

3)finally 关键字 :try-catch-finally

  • 不管之前的执行情况,finally都会执行
  • 用于关闭一些资源
  • 注意:System.exit(0);
2.throws 声明异常:向上抛出

如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。

声明方式:

public void 方法名() throws 异常的类型,异常的类型...{
	代码体:有可能产生异常的代码
	// 读文件的操作可能产生FileNotFoundException类型的异常
	FileInputStream fis = new FileInputStream(file);
}
  • 异常并没有解决,只是抛给了方法的调用者
  • 当前方法中如果采用向上抛出的方式处理异常,则产生异常的代码行一下的代码不执行

在这里插入图片描述
注意:重写方法的声明抛出异常

  • 重写方法不能抛出比被重写方法范围更大的异常类型。
public class A {
 	public void methodA() throws IOException {
 	      ……
 	}  
}
public class B1 extends A {
	public void methodA() throws FileNotFoundException {
	      ……
	}  
}
public class B2 extends A {
	public void methodA() throws Exception {   //报错
	        ……
  	}  
}

7.throw 与 throws的区别

1.throw:抛出异常

异常的生成阶段:可以手动抛出异常对象

2.throws:声明异常

异常的处理方式:用于声明方法可能要抛出的各种异常类

3.try-catch-finally:捕获异常

try:执行可能产生的异常代码——当遇到异常时,JVM底层自动创建一个异常对象,抛出
catch:捕获异常
finally:无论是否发生异常,代码总会被执行

8.自定义异常

步骤:

  1. 新建一个普通类
  2. 继承Exception或者RuntimeException
  3. 实现类的构造器 :通常需要编写几个重载的构造器
  4. 设置serialVersionUID:为了版本兼容

一般地,用户自定义异常类都是RuntimeException的子类

/**
用户自定义异常类MyException,用于描述数据取值范围错误信息。
用户自己的异常类必须继承现有的异常类
*/
class MyException() extends Exception {
	private static final long serialVersionUID = 1L;
	private int idnumber;
 	public MyException(String message, int id) {
		super(message);
		this.idnumber = id;
 	} 
	public int getId() {
		return idnumber;
	}
}
//使用用户自定义异常类
public class Test{
	public void regist(int num) throws MyException {
		if (num < 0) 
			throw new MyException(“人数为负值,不合理”, 3);
		else
			System.out.println("登记人数" + num );
	}
	public void manager() {
		try {
			regist(100);
		} catch (MyException e) {
			System.out.print("登记失败,出错种类"+e.getId());	 	
		}
		System.out.print("本次登记操作结束");
	}
	public static void main(String args[]){
		Test7_5 t = new Test7_5();
		t.manager();
	}
}

类似设置版本号的还有IO流中的对象流,确保传出传入的对象是同一个。

9.异常对象抛出的方式

Java提供的是异常处理的抓抛模型。

  1. 自动抛出:
  • 由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,就会在后台自动创建一个对应异常类的实例对象并抛出
  1. 手动抛出
  • 由开发人员手动创建:Exception exception = new ClassCastException();——创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样

      throw new ArrayIndexOutOfBoundsException(13);
    

10.总结:异常处理的5个关键字

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值