Java异常处理

重要的问题

1、try-catch-finally和throws的区别

try-catch-finally:是真正将异常处理了

throws:只是将异常抛给了方法的调用者,并没有真正将异常处理掉

2、throws和throw的区别

throws是异常处理的一种方式,声明在方法的声明处。

throw表示抛出一个异常类的对象,生成异常对象的过程。声明在方法体中。

1、异常概述

开发过程中的语法错误和逻辑错误不是异常

1、异常是程序执行过程中发生的不正常状况

分为两类:Error和Exception
Error:Java虚拟机无法解决的严重问题,不能用针对性代码处理,只能改代码
Exception:其他因编程错误或偶然外在因素导致的一般性问题,可以使用针对性的代码进行处理。

2、异常分类(可对异常进行处理)

1、编译时异常(可控式异常)

IOException 当发生某种I/O异常时,抛出此异常
ClassNotFoundException 类没有找到异常
SQLException 提供关于数据库访问错误或其他错误信息的异常
NoSuchFieldException 类不包含指定名称的字段时产生的信号
NoSuchMethodException 无法找到某个特定方法时,抛出该异常

2、运行时异常

IndexOutOfBoundsException 数组索引值越界异常(集合或数组的索引值超出范围时抛出该异常)
NullPointerException 空指针异常
ClassCastException 当试图将对象强制转换为不是实例的子类时抛出异常
NumberFormatException 数字格式异常
InputMismatchException 控制台输入的数据类型与设置的不匹配
ArithmeticException 算数异常

补:

开发中由于运行时异常比较常见,我们通常不针对运行时异常编写try-catch-finally了。针对编译时异常,一定要考虑异常的处理。

3、获取异常信息

在Java中Throwable类时所有异常类的超类。
有四种获取异常信息的方法

e.printStackTrace();
e.getMessage();
e.getLocalizedMessage();
e.toString();
public class ExceptionMessage {
    public void printExceptionInfo() { // 定义成员方法
        try {
            int x = 100; // 定义局部变量x
            int y = 0; // 定义局部变量y
            int z = x / y; // 计算x除以y的商
            // 输出计算结果
            System.out.println(x + "除以" + y + "的商是:" + z);
        } catch (Exception e) {
            e.printStackTrace(); // 输出异常到标准错误流
            // 使用getMessage方法输出异常信息
            System.out.println("getMessage方法:   " + e.getMessage());
            // 使用getLocalizedMessage方法输出异常信息
            System.out.println("getLocalizedMessage方法:   " + e.getLocalizedMessage());
            // 使用toString方法输出异常信息
            System.out.println("toString方法:   " + e.toString());
        }
    }
    public static void main(String[] args) {
        ExceptionMessage e = new ExceptionMessage(); // 创建类的实例
        e.printExceptionInfo(); // 调用方法
    }
}

运行结果
在这里插入图片描述

4、处理异常

Java处理异常的模式

1、try-catch-finally
2、throws-异常类型
常用的异常对象处理的方式:e.getMessage() 和e.printStackTtrace()

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

1、使用try-catch处理异常

对代码进行异常检测,并对检测的异常传递给catch处理。对异常进行捕获处理。

格式

try {
   需要正常执行的语句
   } catch(Exception ex) {
     对异常进行处理的语句
   }

2、使用try-catch-finally处理异常

格式

try {
   需要执行的语句
   } catch(Exception ex) {
       对异常进行处理的语句
   } finally {
       一定会被处理的语句
   }

还有多个catch的情况

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

补:
①catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
②如果有子父类关系,则子类一定声明在父类的上面。否则会报错。
③在try结构中声明的变量,在出了try结构后,就不能再被调用
④finally是可选的
⑤try-catch-finally结构可以嵌套
⑥手动的进行资源的释放,需要声明在finally中

3、使用try-finally处理异常

对代码进行异常检测,检测到异常后因为没有catch,所以一样会被默认jvm抛出。异常是没有捕获处理的。但是功能所开启资源需要进行关闭,所有finally。只为关闭资源。

格式

try {
   需要执行的语句
   } finally {
     一定被处理的语句
  }

例子:

public class RuntimeExceptionTest {
	public static void method() {
		try {
			System.out.println("进入方法"); //第1执行
			throw new RuntimeException("制造异常"); //最后执行
		} finally {
			System.out.println("使用方法的finally"); //第2执行,等等再 执行
		}
	}
}
public class test {
	public static void main(String[] args) {
		RuntimeExceptionTest a = new RuntimeExceptionTest();
		try {
			a.method();
		} catch(Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

运行结果
在这里插入图片描述

5、抛出异常

throws关键字可以在定义方法时抛出异常,throw是在方法中抛出异常。

1、使用throws声明抛出异常(是异常处理的第二种方式)

“throws+异常类型”写在方法的声明处,指明此方法执行时可能会抛出的异常类型。异常代码后续的代码就不再执行。

格式

数据类型 方法名(形参列表) throws 异常类1,异常类2,.....,异常类n {
     方法体;
}
public void method() throws IOException {
}

例如

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionTest {
	public void method() throws FileNotFoundException,IOException { //声明在方法中
		File file = new File("hello.txt");
		FileInputStream fis=new FileInputStream(file);
		int d=fis.read();
		while(d!=-1) {
			System.out.println((char)d);
			d=fis.read();
		}
		fis.close();
		System.out.println("不能再执行了!"); //出现异常后这个语句就不再执行了
	}
}
import java.io.IOException;
public class Test {
	public static void main(String[] args) {
		ExceptionTest a = new ExceptionTest();
		try {
			a.method();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

运行结果
在这里插入图片描述

补:开发中如何选择使用try-catch–finally还是使用throws?
①如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,即子类重写的方法中有异常,必须使用try-catch-finally方式处理。父类没有抛异常,子类就不能抛异常。
②在执行的方法a中,先后调用了另外几个方法,这几个方法是递进关系,建议使用throws方式处理,而执行的方法a可以使用try-catch-finally方式处理

2、使用throw语句抛出异常(手动抛出异常对象)

用来抛出一个指定的异常对象

格式

throw new Exception("对异常的说明");

通常使用ExceptionRuntimeException,是自定义的异常类

public class Student {
	private int id;
	public void get(int id) throws Exception {
		if(id>0) {
			this.id=id;
		} else {
		    //System.out.println("您输入的数据非法!"); 以前是这样处理的
			throw new Exception("您输入的数据非法!");
		}
	}
}
public class StudentTest {
	public static void main(String[] args) {
		try {
			Student s = new Student();
			s.get(-100);
			System.out.println(s);
		} catch (Exception e) {
			//e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}
}

运行结果
在这里插入图片描述

6、自定义异常

如何自定义异常类:(步骤)

1、继承于现有的异常结构:Exception、RuntimeException

2、提供全局变量:serialVersionUID

3、提供重载的构造器

1、创建自定义异常类

继承于现有的异常结构:Exception、RuntimeException
提供重载的构造器,形参是异常的描述信息
public class MyException extends Exception {
	/*
	为什么要定义构造函数,因为看到Java中的异常描述类中有提供对异常对象的初始化方法。
	*/
	public MyException() {
		super();
	}
	public MyException(String message)	{
		super(message);// 如果自定义异常需要异常信息,可以通过调用父类的带有字符串参数的构造函数即可。
	}
}

2、使用自定义异常类

通过throw语句抛出异常
MyException类

public class MyException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public MyException() {
		
	}
	public MyException(String s) {
		super(s);
	}
}

Student类

public class Student {
	private int id;
	public void get(int id) throws Exception {
		if(id>0) {
			this.id=id;
		} else {
			throw new MyException("不能输入负数!");
		}
	}
}

Test类

public class Test {
	public static void main(String[] args) throws Exception {
		Student s=new Student();
		try {
			s.get(-100);
			System.out.println(s);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

运行结果
在这里插入图片描述

7、异常的使用原则

①不要过多地使用异常,这样会增加系统的负担
②在方法中使用try-catch捕获异常时,要对异常做出处理
③try-catch语句块的范围不要太大,否则不利于对异常的分析
④一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或子异常

补:

异常在方法重写中细节
子类覆盖父类方法时,如果父类的方法声明异常,子类只能声明父类异常或者该异常的子类,或者不声明。
当父类方法声明多个异常时,子类覆盖时只能声明多个异常的子集。
当被覆盖的方法没有异常声明时,子类覆盖时无法声明异常的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值