Java基础-Exception
来源:互联网 发布:暴雪游戏平台 mac版 编辑:程序博客网 时间:2024/06/04 18:25
Exception in thread “main” java.lang.ArithmeticException: / by zero
异常:程序出现了不正常情况
我们在编写程序的时候,可能会有很多的问题存在。为了将来方便的表示这些的问题的原因,类型,位置。java就提供了异常对象供我们使
用。
举例:
电脑键盘不灵。
原因:敲快了,进水了,线路坏了
解决方案:
A:敲快了–慢点敲
B:进水了–把水弄干
C:线路坏了—买个新的
异常体系:
超类:Throwable
|–Error:严重问题。通常是程序出现重大问题:运行的类不存在或者内存溢出等。是不需要处理的,一般这种情况需要修改代码
|–Exception:问题不严重
非运行时异常:(包括编译异常和其他异常)一般来说,我们只处理编译异常。
运行时异常:这个我们不需要处理,一般需要修改代码。
代码:
public class ExceptionDemo { public static void main(String[] args) { // 运行时期 int a = 10; int b = 0; System.out.println(a / b); // 编译时期,报错 // FileInputStream fis = new FileInputStream("a.txt"); }}
因为这里出现了一个算术异常,我们都知道除数不能为0,Java针对这类算术异常,封装成一个ArithmeticException
通过查API发现,这个类继承自RunnableException这个类,所以是一个运行时异常,在编译期间不会报错,只有在程序运行过程中,才会报错。
如果程序中出现了问题,我们没有去处理,jvm会采用自动的处理方式:
该方式:jvm把异常的类型,原因,位置直接显示在了控制台。
这种方式有一个弊端:
弊端:当程序的某一个位置上出现异常,jvm处理完后,该位置一下的程序就没有执行的机会。
那么,在遇到程序有异常时,我们该怎么做?
A:编写处理代码:
基本格式:
try{
可能发生问题的地方
}catch(异常类名 变量名){
异常处理代码
}finaly{
//这里是一定会执行的代码,通常是一些释放资源的操作
}
B:在方法体上抛出该异常
当我们采用编写处理代码的方式处理异常时,即使程序在某处发生了异常,而我们已经处理了,所以,异常处代码下面的程序会继续执行,不会受其影响。
代码:
public class ExceptionDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入被除数:"); int a = sc.nextInt(); System.out.println("请输入除数:"); int b = sc.nextInt(); try { int c = a / b; System.out.println(c); } catch (ArithmeticException ae) { // 继续操作 // 返回一个错误页面 System.out.println("除数不能为0"); } System.out.println("新年快乐"); }}
从控制台输出可以看出,即使在 int c = a / b; 这里出现了问题,除数为0.。。。。程序最下面的 新年快乐 ,还是输出来了。
那么,如果一个代码中如果出现多种问题(多种异常),该如何解决呢?
A:每一个异常有可能出现的地方,都用一个try{}…catch(){} 来处理
B:针对所有可能出现异常的地方,使用一个try{}将所有地方都括起来,然后后面跟多个catch(){}语句,分别捕捉对应的异常类
格式:
try{
。。。。。。
}catch(){
。。。。。。
}catch(){
。。。。。。
}
注意:在异常处理中,一旦捕捉到异常,就会直接跳到对应的catch里面执行处理代码。不管异常发成处下方,是否还有其他语句,都不会执行,直接跳到catch里面。
方式A处理代码:
public class ExceptionDemo2 { public static void main(String[] args) { method1(); } // 针对每一个异常写一个try...catch代码。 public static void method1() { // ArithmeticException int a = 10; int b = 0; try { System.out.println(a / b); System.out.println("hello"); } catch (ArithmeticException ae) { System.out.println("除数不能为0"); } // ArrayIndexOutOfBoundsException int[] arr = { 1, 2, 3 }; try { System.out.println(arr[3]); } catch (ArrayIndexOutOfBoundsException ae) { System.out.println("数组越界异常"); } // 继续操作 System.out.println("over"); }}
处理方式B代码:
public class ExceptionDemo2 { public static void main(String[] args) { method2(); } public static void method2() { try { // ArithmeticException int a = 10; // int b = 0; int b = 2; System.out.println(a / b); // ArrayIndexOutOfBoundsException 当上面捕获异常,下面的代码不会执行,因为上面并没有异常,所以这里的代码被执行 int[] arr = { 1, 2, 3 }; System.out.println(arr[3]); // 不会被执行,因为上面已经捕获异常,直接跳到catch里面执行 System.out.println("over"); } catch (ArithmeticException ae) { System.out.println("除数不能为0"); } catch (ArrayIndexOutOfBoundsException ae) { System.out.println("数组越界异常"); } }}
注意:异常或者错误,都是以他们所在体系的父亲作为后缀。
XxxException
XxxError
针对多个异常,写一个try的代码,catch里面会不会有顺序问题呢?
如果异常是平级关系,没有顺序问题。
如果异常存在着子父关系,父一定要放在最后。
代码如下:
public class ExceptionDemo3 { public static void main(String[] args) { // method1(); // method2(); method3(); } public static void method3() { try { // ArithmeticException int a = 10; // int b = 0; int b = 2; System.out.println(a / b); // ArrayIndexOutOfBoundsException int[] arr = { 1, 2, 3 }; // System.out.println(arr[3]); System.out.println(arr[2]); // 这里又出现了一个问题,这里很明显是一个空指针问题。 // 假设我们忘了,也就是说我们不知道这是一个什么异常。 // 怎么处理呢? String s = null; System.out.println(s.length()); // 继续操作 System.out.println("over"); } catch (Exception e) { System.out.println("空指针问题"); } // catch (ArrayIndexOutOfBoundsException ae) { // System.out.println("数组越界异常"); // } catch (ArithmeticException ae) { // System.out.println("除数不能为0"); // } } public static void method2() { try { // ArithmeticException int a = 10; // int b = 0; int b = 2; System.out.println(a / b); // ArrayIndexOutOfBoundsException int[] arr = { 1, 2, 3 }; // System.out.println(arr[3]); System.out.println(arr[2]); // 这里又出现了一个问题,这里很明显是一个空指针问题。 // 假设我们忘了,也就是说我们不知道这是一个什么异常。 // 怎么处理呢? String s = null; System.out.println(s.length()); // 继续操作 System.out.println("over"); } catch (Exception e) { System.out.println("空指针问题"); } } public static void method1() { try { // ArithmeticException int a = 10; // int b = 0; int b = 2; System.out.println(a / b); // ArrayIndexOutOfBoundsException int[] arr = { 1, 2, 3 }; // System.out.println(arr[3]); System.out.println(arr[2]); // 这里又出现了一个问题,这里很明显是一个空指针问题。 // 假设我们忘了,也就是说我们不知道这是一个什么异常。 // 怎么处理呢? String s = null; System.out.println(s.length()); // 继续操作 System.out.println("over"); } catch (ArrayIndexOutOfBoundsException ae) { System.out.println("数组越界异常"); } catch (ArithmeticException ae) { System.out.println("除数不能为0"); } catch (Exception e) { System.out.println("空指针问题"); } }}
里面有三个方法,每一个方法,测试的是一种情况,method1方法中,把Exception放在了catch最后面,method2方法中,只使用了Exception类来接收收到异常;method3方法中,因为将Exception放在了catch的最前面,因此在其下面的两个子类,就不会被执行到,不注释掉会产生编译异常。
*JDK7新特性:多个catch用一个catch替代。 不是说多个catch的内容,用一个Exception处理。
格式:
catch(异常1 | 异常2 | 异常3 … 变量名){}*
代码如下:
public class ExceptionDemo4 { public static void main(String[] args) { // method(); method2(); } private static void method2() { try { // ArithmeticException int a = 10; // int b = 0; int b = 2; System.out.println(a / b); // ArrayIndexOutOfBoundsException int[] arr = { 1, 2, 3 }; // System.out.println(arr[3]); System.out.println(arr[2]); // 这里又出现了一个问题,这里很明显是一个空指针问题。 // 假设我们忘了,也就是说我们不知道这是一个什么异常。 // 怎么处理呢? String s = null; System.out.println(s.length()); // 继续操作 System.out.println("over"); } catch (ArrayIndexOutOfBoundsException | ArithmeticException | NullPointerException ae) { //这里暂时输出一个语句 //当学习了printStackTrace()后,可以直接ae.printStackTrace(); System.out.println("这里出问题了"); } } private static void method() { try { // ArithmeticException int a = 10; // int b = 0; int b = 2; System.out.println(a / b); // ArrayIndexOutOfBoundsException int[] arr = { 1, 2, 3 }; // System.out.println(arr[3]); System.out.println(arr[2]); // 这里又出现了一个问题,这里很明显是一个空指针问题。 // 假设我们忘了,也就是说我们不知道这是一个什么异常。 // 怎么处理呢? String s = null; System.out.println(s.length()); // 继续操作 System.out.println("over"); } catch (ArrayIndexOutOfBoundsException ae) { System.out.println("数组越界异常"); } catch (ArithmeticException ae) { System.out.println("除数不能为0"); } catch (NullPointerException ne) { System.out.println("空指针问题"); } }}
Throwable中的方法:
A:public String getMessage():返回的是异常的消失字符串
B:public String toString():返回的是异常的简单描述信息
格式: 全路径名:消息字符串
C:public void printStackTrace():把错误的信息显示在控制台
方法A中的代码:
public class ExceptionDemo { public static void main(String[] args) { int a = 10; int b = 0; try { System.out.println(a / b); // 一旦发生问题,在这里其实就产生了一个ArithmeticException对象。 // 然后,拿着这个对象,去和catch里面的类型进行匹配。如果有,就赋值。 // new ArithmeticException() } catch (ArithmeticException ae) { // ArithmeticException ae = new // ArithmeticException(); // System.out.println("除数不能为零"); // 通过分析,那么,ae是一个对象了 // / by zero System.out.println(ae.getMessage()); // java.lang.ArithmeticException: / by zero System.out.println(ae.toString()); // 实际开发中,会获取到异常后,自动判断是某种异常,然后一个错误信息处理界面。 ae.printStackTrace(); } System.out.println("over"); }}
异常处理的完整代码:
格式:
try{
可能有问题的代码
}catch(异常类名 变量名){
处理方案。变量名.printStackTrace();
}finally{
释放资源。(数据库,IO)
}
finally:里面代码永远会执行。
代码:
public class FinallyDemo { public static void main(String[] args) { int a = 10; int b = 0; try { System.out.println(a / b); } catch (ArithmeticException ae) { ae.printStackTrace(); } finally { System.out.println("over"); } }}
![这里写图片描述](http://img.blog.csdn.net/20150807002810723) 分析: 这里永远都会打印在finally里面的over
面试题:
2:finally里面的代码真的永远会执行吗?
* 会永远执行。但是有一个特殊情况:在代码执行到finally之前,jvm就退出了。
* 3:加入在catch里面有return语句,请问finally里面的代码还会执行吗?如果执行,是在return前,还是return后?
* 会执行。在return前执行。
* 准确答案:在return之间执行。
代码:
public class FinallyTest { public static void main(String[] args) { method2(); int result = method3(); System.out.println(result); } private static int method3() { int a = 10; try { System.out.println(a / 0); System.out.println("a1:" + a); } catch (ArithmeticException ae) { System.out.println("a2:" + a); // a2:10 a = 20; return a; //这个时候,在内存中就会有一个路径产生,该路径返回值是20. //但是,它看到了finally代码块,所以,继续执行finally里面的内容 //当finally里面结束后,会回到以前的执行路径。 } finally { System.out.println("a3:" + a); // a3:20 a = 30; return a; }// return a; } private static void method2() { int a = 10; int b = 0; try { System.out.println(a / b); } catch (ArithmeticException ae) { ae.printStackTrace(); return; } finally { System.out.println("over"); } }
分析: 上面打印出来的是method2方法调用时,printStackTrace()的信息 下面的都是method3方法调用时,输出的数值。。。这里面的值,说明了finally里面的语句一定会执行
Java中的自定义异常:
java虽然已经考虑到了很多种异常情况,但是,有些需求java程序是考虑不到的。比如说:我要求学生的分数不能为负数。 那么,针对这种情况,我们就要编写自定义异常类进行处理。 如何编写一个自定义异常类呢? 就是自定义一个类,去继承Exception或者RuntimeException。 开发中:一般继承自RuntimeException。 我先讲Exception。自定义异常类MyException的代码如下:
public class MyException extends Exception { public MyException(String message) { super(message); }}
使用异常类MyException的代码如下:
/* * 一旦你的判断需要做某些异常处理的时候, 你就应该在方法内部用throw关键字把该异常对象抛出。 * 格式: * 方法内部 * throw 异常对象; */public class Teacher { public void checkScore(int score) throws MyException { if (score < 0 || score > 100) { // System.out.println("分数错误"); MyException my = new MyException("分数不在指定范围内"); throw my; } else { System.out.println("分数正确"); } }}
测试类中的代码:
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(); Teacher t = new Teacher(); try { t.checkScore(score); } catch (MyException e) { System.out.println(e.getMessage()); // e.printStackTrace(); } // t.checkScore(score); }}
![这里写图片描述](http://img.blog.csdn.net/20150807004449743)结果分析:输入一个-1,会输出自定义异常里面定义好的信息message。
- java基础---->Exception
- Java基础----Exception
- java基础:Exception异常
- Java 异常基础 Exception
- Java基础-Exception
- Java基础-Exception
- java Exception 基础
- Java基础 Exception
- Java 异常基础 Exception
- Java 异常基础 Exception
- java 异常基础 Exception
- Java 异常基础 Exception
- JAVA基础--自定义异常exception
- 黑马程序员---java基础之异常(Exception)
- 黑马程序员--Java基础之异常Exception
- 黑马程序员--------java基础 Exception (异常)
- Java基础第十五天--Exception异常
- Java基础学习总结---------异常Exception(2)
- 黑马程序员--IO流总结--java
- 基础知识普及帖:百度搜索引擎的工作流程
- (国庆)溧阳天目湖,广德太极洞
- Codeforces Round #Pi (Div. 2) E
- OCUI界面设计:标签控制器
- Java基础-Exception
- Java基础-Collection之Set的实现
- copy_from_user/copy_to_user函数中的buf参数释疑
- Linux-C网络编程之epoll函数
- Windows10 显示库、隐藏6个文件夹、隐藏OneDrive
- ContentProvider的简单虚拟短信
- uva 1670 Kingdom Roadmap(图论构造题)
- iOS之学习CoreData的笔记
- _DataStructure_C_Impl:Array