1.异常的分类:
(1)严重问题:不去处理
(2)编译时期异常:只要不是RuntimeException中的异常都属于编译时期异常
出现的原因:语法有问题,要么使用的是Sun公司提供的一些类的中的方法(这个方法本身调用的时候就会异常存在,调用者必须处理,不处理编译不通过)
(3)运行时期异常:RuntimeException
可能由于我们代码的逻辑不够严谨导致的问题,例:NullPointerException:空指针异常
2.异常的处理方式:
(1)try { }...catch(){ }...finally { }来捕获异常并进行处理
(2)throws抛出异常
3.异常中的常用方法:
(1)public String getMessage()消息字符串
(2)public String toString()描述字符串
1)当前类的全路径名称(指的是当前异常类名所在的包的全路径名称)
2)": "(冒号和一个空格)
(3)public void printStackTrace()输出异常的类型和位置
该方法是里面包含了消息字符串以及当前出现错误的异常的时候所描述哪个包下以及代码中具体的错误出现第几行
返回值是void,也就直接在控制台输出
4.继承中异常的注意事项:
(1)子类在重写父类中的方法时,如果父类的方法抛出异常,那子类重写的这个方法抛出的异常不能比父类大(可以为父类中异常方法的子类,或者最起码应该与父类保持一致)
(2)子类继承父类要重写父类的方法时,若父类中该方法本身不存在异常,则子类在重写该方法时只能去使用try-catch去捕获异常,而不能使用throws去抛出异常!
5.Java中的常见异常类
异常类 | 说明 |
---|---|
ClassCastException | 类型转换异常 |
ClassNotFoundException | 未找到相应异常类 |
ArithmeticException | 算数异常 |
ArrayIndexOutOfBoundsException | 数组下标越界异常 |
ArrayStoreException | 数组中包含不兼容的值抛出的异常 |
SQLException | 操作数据库异常类 |
NullPointerException | 空指针异常 |
NoSuchFieldException | 字段未找到异常 |
NoSuchMethodException | 方法未找到抛出的异常 |
NumberFormatException | 字符串转换为数字抛出的异常 |
NegativeArraySizeException | 数组元素个数为负数抛出的异常 |
StringIndexOutOfBoundsException | 字符串索引超出范围抛出的异常 |
IOException | 输入输出异常 |
IllegalAccessException | 不允许访问某类异常 |
EOFException | 文件已结束异常 |
FileNotFoundException | 文件未找到异常 |
异常的处理方式1:try...catch()...方法
1.处理单个异常
try{
很多行代码(一旦有出现问题了,处理错误代码)
}catch(异常类名 变量名){
输出语句处理
}
例:
public class ExceptionDemo {
public static void main(String[] args) {
// 定义两个变量
int a = 10;
int b = 0;
// 输出
try {
// try中:是可能会出现问题的代码
System.out.println(a / b);
// 针对问题给出具体的异常类:
} catch (Exception e) {
e.printStackTrace();
// System.out.println("除数不能为0");
}
System.out.println("over");
}
}
2.处理多个异常
try{
可能会出现问题的多个语句
}catch(异常类名1 变量名){
输出语句处理
}catch(异常类名2 变量名){
输出语句处理
}
······
注:1.针对多个异常进行处理,如果catch中给的第一个是大异常(Exception)则后面的异常就不用再给出了
解决办法:将大异常置于小异常之后
2.多个异常一起进行处理时,只要try语句中的代码和catch中描述的异常类型一致,则直接运行catch里的语句结束
例:
public class ExceptionDemo {
public static void main(String[] args) {
method();
}
private static void method() {
int a=10;
int b=0;
int [] arr = {1,2,3};
try{
//可能出现问题的代码
System.out.println(a/b);
System.out.println(arr[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("您访问了数组中不存在的索引");
}
//* catch到try语句中的"System.out.println(a/b);"代码有异常,则直接走此catch中的语句结束!!!
catch(ArithmeticException e){
System.out.println("除数不能为0");
}
//* 大异常必须至于小异常之后!!!若大异常在小异常之前,则其后小异常不用再给出!!!
catch(Exception e){
System.out.println("可能会出现问题");
}
System.out.println("over");
}
}
3.针对多个异常处理的方法,JDK7以后给出了新的处理方式:
try{
//可能会出现问题的代码
//....
//...
}catch(异常类名1 | 异常类名2 ....变量名){
处理异常...
}
注:1.使用此方法进行异常的处理时,要求catch的各个异常类名之间是一种平级的关系
2.这种格式在开发中,需要针对具体的异常给出具体的处理
例:
public class ExceptionDemo {
public static void main(String[] args) {
// 定义变量及数组
int a = 10;
int b = 0;
int[] arr = { 1, 2, 3 };
try {
System.out.println(a / b);
System.out.println(arr[3]);
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("程序出现问题了");
e.printStackTrace();
}
System.out.println("over");
}
}
*练习:(try...catch()...方法解决日期的“解析”)(注解析时该方法本身就会抛出异常)
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo {
public static void main(String[] args) {
method();
}
private static void method() {
// String日期"文本"格式---->Date格式:解析
String s = "2017-11-21";
// 创建SimpleDataFormat对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 调用parse()方法进行解析
Date d;
try {
d = sdf.parse(s);
System.out.println("d:" + d);
} catch (ParseException e) {
e.printStackTrace();//打印出此异常
System.out.println("解析出现问题");
}
}
}
异常处理的标准格式:try { }...catch(){ }...finally { }
public class FinallyDemo {
public static void main(String[] args) {
System.out.println(getInt());
}
private static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
/**
* 代码在此处return 30 ,在这里形成了一个方法返回路径
* 但finally中的代码还会执行a=40,不过由于之前已经返回路径
* 所以代码就要执行到return之前
*/
} finally {
a = 40;
}
return a;
}
}
//结果:30
异常的处理方式2:throws
1.异常的处理方式2:抛出异常(throws & throw)
注:抛出异常:throws和throw的区别!
(1)throws(用于方法声明上):
后面跟异常类名(可跟多个异常类名,中间用“,”隔开)
throws在方法声明上抛出,表示异常的一种可能性
由调用者去进行处理
注:使用throws关键字将异常抛给上一级后,如果不想处理该异常可以继续向上抛,但最终要有能够处理高异常的代码
(2)throw(用于方法体中):
后面跟的是异常对象(常使用匿名对象 的方式),只可跟一个具体的异常对象
throw在方法中的语句抛出,表示异常的绝对性
由方法中的语句进行处理
注:程序在执行到throw语句时立即终止,后面的语句都不执行
自定义异常类
//功能:测试分数是否满足在0-100之间
import java.util.Scanner;
//测试类
public class MyExceptionDemo {
public static void main(String[] args) {
// 创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请您输入一个分数:");
int score = sc.nextInt();
//步骤④:捕获并处理异常
try {
check(score);
} catch (MyException e) {
System.out.println(e);
}
}
// 自定义一个检查分数的方法
//步骤③:在方法声明处通过throws抛出异常
public static void check(int score) throws MyException {
if (score > 100 || score < 0) {
//步骤②:在方法中通过throw关键字抛出异常对象
throw new MyException("方法1:您输入的分数有误");
} else {
System.out.println("分数的值属于正确范围");
}
}
}
// 步骤①:自定义的一个异常类
class MyException extends Exception {
public MyException() {
}
public MyException(String message) {
super(message); //父类构造方法:构造带指定详细消息的新异常
}
}
例2:在当前抛出异常的方法中通过try-catch捕获并处理异常
//功能:测试分数是否满足在0-100之间
import java.util.Scanner;
//测试类
public class Test {
public static void main(String[] args) {
// 创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请您输入一个分数:");
int score = sc.nextInt();
check(score);
}
// 自定义一个检查分数的方法
public static void check(int score) {
// 针对分数进行判断
if (score > 100 || score < 0) {
//步骤③:在当前抛出异常的方法中使用try-catch捕获并处理异常(可以不用在方法声明上使用throws抛出异常)
try {
//步骤②:在方法中通过throw关键字抛出异常对象
throw new MException("方法2:您输入的分数有误");
} catch (MException e) {
System.out.println(e);
}
} else {
System.out.println("分数的值属于正确范围");
}
}
}
// 步骤①:自定义一个异常类
class MException extends Exception {
public MException() {
}
public MException(String message) {
super(message); //父类构造方法:构造带指定详细消息的新异常
}
}