异常

一、异常处理

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中可以通过类对这一类不正常的现象进行描述,并封装为对象

5、异常的语法

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("程序结束!!!");

}

6、异常的分类

Java异常体系

|——Throwable  (实现类描述java的错误和异常)

|——Error (错误)一般不通过代码去处理。

|——Exceprion (异常)

 |——RuntimeException (运行时异常)

 |——非运行时异常(受检查异常)

 

7、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();

}

}

 

报错信息

Exception in thread "main" java.lang.StackOverflowError

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

at com.offcn.yichang.Demo03_Error.fun(Demo03_Error.java:12)

8、Throwable类

  1. toString() 输出该异常的类名。
  2. getMessage() 输出异常的信息,需要通过构造方法传入异常信息(例如病态信息)。
  3. printStackTrace() 打印栈信息。

人生病:流鼻涕,感冒,呼吸道感染,肺炎。。。最后体现的是肺炎。

医生要处理需要获知这些信息。从外到里处理。最后找病源。

// Throwable able=new Throwable();

Throwable able = new Throwable("想吐。。。");

System.out.println(able.toString()); // 输出该异常的类名

System.out.println(able.getMessage()); // 输出异常的信息

able.printStackTrace(); // 打印栈

9、 运行时异常和非运行时异常

(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();

}

  1. 多重catch块

格式

try {

   代码段

   产生异常(异常类型2)

} catch (异常类型1 e) {

   对异常进行处理的代码段

} catch (异常类型2 e) {

    对异常进行处理的代码段

} catch (异常类型3 e) {

    对异常进行处理的代码段

}

代码段

 

 

示例代码

public class Demo07_多重catch块 {

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块是必须的。

异常捕获的先后顺序应该“从小到大”。

11、程序中的异常处理

(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");

}

throw和throws的区别

  • throw是对异常对象的抛出,throws是对异常的声明。
  • throw是实实在在地抛出对象,一旦使用throw,一定会产生异常对象,throw只能跟一个异常对象。
  • throws后面跟的异常的类名,可以跟多个,使用逗号隔开。

12、自定义异常

问题:现实中会出现新的病,就需要新的描述。

分析: Java的面向对象思想将程序中出现的特有问题进行封装。

当jdk内置异常类型不足以满足系统需求时,我们需要自定义异常类型。

使用自定义异常和使用jdk内置异常是一回事。

 

自定义异常的方式: 继承Exception 或 RuntimeException

 

示例代码

//自定义的运行时异常

public class MyException extends RuntimeException{

/*

 * 在自定义异常时,完全可以自定义一些属性和方法。但多数时间不需要这样做

 * */

public MyException(){

 

}

public MyException(String message){

super(message);

}

}

 

示例代码2

// 自定义一个非运行时异常

public class MyException2 extends Exception {

  public MyException2(){

  

  }

      public MyException2(String message){

  super(message);

  }

}

案例:模拟吃饭没带钱的问题

  1. 定义吃饭功能,需要钱。(例如:eat(double money))
  2. 如果钱不够是不能吃饭,有异常。
  3. 自定义NoMoneyException();继承Exception 提供有参无参构造,调用父类有参构造初始化。eat 方法进行判断,小于10块,throw NoMoneyException("钱不够");
  4. eat 方法进行声明,throws NoMoneyException;
  5. 如果钱不够老板要处理。调用者进行处理。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("吃桂林米粉");

}

}

13、finally

catch的目的,抓住出现的异常情况,使工作维持正轨。

finally的目的:

      有某些事情,相当重要,即便是发生了异常,也不应该被跳过。

      比如:还债

finally到底用在哪?

 

宋丹丹的经典错误:

开冰箱门

装入大象

关冰箱门

try {

开冰箱门

装入大象

关冰箱门

}

catch() {

修理大象

}

错在哪?  如果装大象的时候出了问题,冰箱门将不能关闭。

完美的方案:

打开冰箱门

try

{  

    装入大象

}

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");

    }

}

 

考考你:

1…

try{

   2…

   3…

   4…

}

finally{

   5…

}

   6…

请分别说出正常与异常执行的流程?

正常时:

1处发生异常:

3处发生异常:

14、常见异常举例

RuntimeException    Java.lang包中多数异常的基类

ArithmeticException    算术异常,如除以0

ArrayIndexOutOfBoundsException 数组下标出界

NullPointerException 试图访问null对象引用

SecurityException 试图违反安全性

ClassNotFoundException 不能加载请求的类

NumberFormatException 字符串到数字格式的非法转换

IOException  I/O异常的根类  

FileNotFoundException  不能找到文件

IllegalAccessException 对类的访问被拒绝

NoSuchMethodException 请求的方法不存在

InterruptedException 线程中断

NullPointerException空指针异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值