目录
一、异常的概述
1、现实生活的病
现实生活中万物在发展和变化会出现各种各样不正常的现象。
1:例如:人的成长过程中会生病。
|——病
|——不可治愈(癌症晚期)
|——可治愈
|——小病自行解决(上火,牙痛)
|——去医院(发烧)
2、程序中意外情况的处理方式
1 传统方式:用if语句进行判断,并作相应的处理。
public static void main(String[] args) {
int x = 10;
int y = 0;
if(y==0){
System.out.println("除数不能为0");
}else{
int result = x/y;
System.out.println(result);
}
System.out.println("程序结束!!!");
}
2 抛出异常,捕获异常的机制。
3、异常的含义
异常是java处理错误的一种机制。
设计良好的程序应该在异常发生的时候提供处理这些错误的方法,使得程序不会因为异常的发生而阻断。
String friends[]={"tom","john","jenni"};
for(int i=0;i<4;i++){
System.out.println(friends[i]);
}
System.out.println("程序结束");
以上程序会因数组下标超出范围而中断,不会输出“程序结束“
4、java异常处理的机制
把异常的发现和处理相分离。
现实生活中的很多病况从面向对象的角度考虑也是一类事物,可以定义为类。
java中可以通过类对这一类不正常的现象进行描述,并封装为对象。
二、异常的语法
Java的异常处理是通过5个关键字来实现的:try、catch、 finally、throw、throws。
使用try catch 来捕获异常
public void method(){
try {
可能产生异常的 代码段
} catch (异常类型 e) {
对异常进行处理的代码段
}
代码段
}
说明
try{ } 块表示受到监控的代码。其中一但发生情况,就会按照是哪种情况,跳到catch块中执行。
e 是产生的异常对象的名字。每个异常发生的时候,都会有对应的异常对象。它记录了异常的详细信息。
public static void main(String[] args) {
String friends[]={"tom","john","jenni"};
try{
for(int i=0;i<4;i++){
System.out.println(friends[i]);
}
System.out.println("程序结束");
}catch(ArrayIndexOutOfBoundsException e){
/*System.out.println(e);
System.out.println("数组下标越界了.........");
e.printStackTrace();*/
System.out.println(e.getMessage());
}
System.out.println("程序结束!!!");
}
三、异常的分类
java异常体系
|——Throwable (实现类描述java的错误和异常)
|——Error (错误)一般不通过代码去处理。
|——Exceprion (异常)
|——RuntimeException (运行时异常)
|——非运行时异常(受检查异常)
四、Error
错误(Error):
它指的是一个合理的应用程序不能截获的严重的问题。大多数都是反常的情况。错误是JVM的一个故障(虽然它可以是任何系统级的服务)。所以,错误是很难处理的,一般的开发人员是无法处理这些错误的。比如内存溢出,栈溢出等。
public class Demo03_Error {
public static void main(String[] args) {
fun(); //java.lang.StackOverflowError Error 不需要使用try catch处理
}
public static void fun(){
fun();
}
}
五、Throwable类
-
toString() 输出该异常的类名。
-
getMessage() 输出异常的信息,需要通过构造方法传入异常信息(例如病态信息)。
-
printStackTrace() 打印栈信息。
人生病:流鼻涕,感冒,呼吸道感染,肺炎。。。最后体现的是肺炎。
医生要处理需要获知这些信息。从外到里处理。最后找病源。
// Throwable able=new Throwable();
Throwable able = new Throwable("想吐。。。");
System.out.println(able.toString()); // 输出该异常的类名
System.out.println(able.getMessage()); // 输出异常的信息
able.printStackTrace(); // 打印栈
六、运行时异常和非运行时异常
(1)运行时异常(RuntimeException)
运行时异常,不要求程序必须对它们做出处理。(在程序的编译期不会检查这种异常)
RuntimeException的子类:
ClassCastException
多态中,可以使用Instanceof 判断,进行规避
ArithmeticException
进行if判断,如果除数为0,进行return
NullPointerException
进行if判断,是否为null
ArrayIndexOutOfBoundsException
使用数组length属性,避免越界
public class Demo05_运行时异常 {
public static void main(String[] args) {
Animal a = new Cat();
Dog d = (Dog)a;
String str = null;
"aaa".equals(str);
str.charAt(0);
str.concat("aaa");
}
}
class Animal{
}
class Cat extends Animal{
}
class Dog extends Animal{
}
说明
这些异常是可以通过程序员的良好编程习惯进行避免的。
1:遇到运行时异常无需进行处理,直接找到出现问题的代码,进行规避。
2:就像人上火一样牙疼一样,找到原因,自行解决即可
3:该种异常编译期不会检查程序员是否处理该异常
4:如果是运行时异常,那么没有必要在方法上进行声明。
(2)非运行时异常(受检查异常)
如果出现了非运行时异常必须进行处理 throw或者try{}catch(){}处理,否则编译期报错。
1:IOException 使用要导入包import java.io.IOException;
2:ClassNotFoundException
3:FileNotFoundException
4:ParseException
例如人食物中毒,必须进行处理,要去医院进行处理。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d = sdf.parse("aaa-10-10");
} catch (ParseException e) {
e.printStackTrace();
}
七、多重catch块
格式:
try {
代码段
产生异常(异常类型2)
} catch (异常类型1 e) {
对异常进行处理的代码段
} catch (异常类型2 e) {
对异常进行处理的代码段
} catch (异常类型3 e) {
对异常进行处理的代码段
}
代码段
public static void main(String[] args) {
try {
int x = 10;
int y = 0;
int result = x/y;
int[] aa = {1,2,3};
System.out.println(aa[1]);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.parse("1111-11-11");
Object obj = new Object();
Date d = (Date)obj;
}catch(Exception e){
System.out.println("程序出错了~~~~~~~~~");
}
/*catch (ParseException e) {
System.out.println("转换错误");
}catch(ArithmeticException e){
System.out.println("运算错误");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("数组下标越界");
}catch(NullPointerException e){
System.out.println("空指针");
}*/
}
说明
单个try块能有许多catch块,当try块有“可能引起不同类型异常”的语句时,多个catch块是必须的
异常捕获的先后顺序应该“从小到大”
八、程序中的异常处理
(1)自行处理
使用try{}catch()语句,保证程序可以正常运行
(2)throws 关键字
当程序中发生异常时,无论是程序运行出现的运行时异常,编译阶段的非运行时异常,还是手工抛出的异常,都可以在程序中使用try{}catch进行处理。但也可以在当前的程序(也就是当前方法中),不做任何处理。使用throws关键字在方法声明时,进行异常的抛出。交给方法的调用者去处理,当方法的调用者也不知道如何处理,或不想处理时,可以继续向上抛出
格式:
类型 方法名(参数列表) throws 异常列表{
代码
}
public static void method() throws ParseException,FileNotFoundException{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String str = "aaaa-11-11";
Date d = sdf.parse(str);
FileInputStream is = new FileInputStream("D:/aaa.txt");
}
(3)手工抛出异常 (throw关键字)
手工抛出异常,其效果和程序抛出异常是一样的,只是它是人为地抛出。
抛出异常的格式为:throw ThrowableObject
例如:throw new ArithmeticException();
public static void main(String args[]) {
System.out.print("Now");
try {
System.out.print("is");
throw new NullPointerException(); // 直接抛出一个异常 ;
// System.out.print("This will not execute!"); //此句不被执行
} catch (NullPointerException m) {
System.out.print("the");
}
System.out.print("time. \n");
}
九、自定义异常
问题:现实中会出现新的病,就需要新的描述。
分析: java的面向对象思想将程序中出现的特有问题进行封装。
当jdk内置异常类型不足以满足系统需求时,我们需要自定义异常类型。
使用自定义异常和使用jdk内置异常是一回事。
自定义异常的方式: 继承Exception 或 RuntimeException
//自定义的运行时异常
public class MyException extends RuntimeException{
/*
* 在自定义异常时,完全可以自定义一些属性和方法。但多数时间不需要这样做
* */
public MyException(){
}
public MyException(String message){
super(message);
}
}
// 自定义一个非运行时异常
public class MyException2 extends Exception {
public MyException2(){
}
public MyException2(String message){
super(message);
}
}
案例:模拟吃饭没带钱的问题
-
定义吃饭功能,需要钱。(例如:eat(double money))
-
如果钱不够是不能吃饭,有异常。
-
自定义NoMoneyException();继承Exception 提供有参无参构造,调用父类有参构造初始化。eat 方法进行判断,小于10块,throw NoMoneyException("钱不够");
-
eat 方法进行声明,throws NoMoneyException
如果钱不够老板要处理。调用者进行处理。try{}catch(){} 。
class NoMoneyException extends Exception {
NoMoneyException() {
}
NoMoneyException(String message) {
super(message);
}
}
class Demo11 {
public static void main(String[] args) {
System.out.println();
try {
eat(0);
} catch (NoMoneyException e) {
System.out.println("跟我干活吧。");
}
}
public static void eat(double money) throws NoMoneyException {
if (money < 10) {
throw new NoMoneyException("钱不够");
}
System.out.println("吃桂林米粉");
}
}
十、finally
catch的目的,抓住出现的异常情况,使工作维持正轨。
finally的目的:
有某些事情,相当重要,即便是发生了异常,也不应该被跳过
finally通常用在:代码中有必须要执行的代码(比如释放资源)的情况
注意: 同样也有 try{}finally{} 结构。
public static void main(String[] args) {
/*
System.out.println("111");
try{
System.out.println("222");
int result = 10/0;
System.out.println("333");
}catch(Exception e){
System.out.println("444");
//return;
String str = null;
str.charAt(0);
}
System.out.println("555");
*/
System.out.println("111");
try{
System.out.println("222");
int result = 10/0;
System.out.println("333");
}catch(Exception e){
System.out.println("444");
//return;
//即使有return finally的代码也要执行,在return之前执行
String str = null;
str.charAt(0);
}finally{
System.out.println("555");
}
}
十一、常见异常举例
RuntimeException | Java.lang包中多数异常的基类 |
ArithmeticException | 算术异常,如除以0 |
ArrayIndexOutOfBoundsException | 数组下标出界 |
NullPointerException | 试图访问null对象引用 |
SecurityException | 试图违反安全性 |
ClassNotFoundException | 不能加载请求的类 |
NumberFormatException | 字符串到数字格式的非法转换 |
IOException | I/O异常的根类 |
FileNotFoundException | 不能找到文件 |
IllegalAccessException | 对类的访问被拒绝 |
NoSuchMethodException | 请求的方法不存在 |
InterruptedException | 线程中断 |
NullPointerException | 空指针异常 |
下一篇:(45)Java基础 --集合