1、java 异常
异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。
异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。
Java通过API中 Throwable 类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件。当条件生成时,错误将引发异常。
Java异常类层次结构图:
java中将程序出现问题封装成了一个 Throwable 类 Throwable 分两种:Error(错误)和Exception(异常) Error(错误):严重问题,指运行时环境发生的错误,由jvm自动生成并抛出。例如JVM 内存溢出。
Exception(异常):不严重的问题,程序可以处理也必须要处理的(重点)
注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。
异常(Exception)分两种:
RuntimeException(运行时期异常): 在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错),可处理,可不处理。
编译时期异常:除了运行期异常以外,其他全是编译时期异常,在编译时期,就会检查,如果没有处理异常,则编译失败不能运行。
2、处理异常机制
异常处理机制为:抛出异常,捕捉异常。
java.lang.Throwable常用方法等:
-
-
Throwable
getCause()
如果原因不存在或未知,则返回此throwable的原因或
null
。String
getLocalizedMessage()
创建此可抛出的本地化描述。
String
getMessage()
返回此throwable的详细消息字符串。
StackTraceElement[]
getStackTrace()
提供对
printStackTrace()
打印的堆栈跟踪信息的void
printStackTrace()
将此throwable和其追溯打印到标准错误流。
-
try{
需要被监测的代码块
}catch(异常的名称 引用名称){
处理方式
}finally{
无论是否捕获或处理异常,finally块里的语句都会被执行。
当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。永远返回finally中的结果。
在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit(0)退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
}
注意: 1)try和catch都不能单独使用,必须连用。finally不能单独使用. 2)finally有return语句,永远返回finally中的结果,避免使用该情况。 执行的流程:当需要被监测的代码块中一旦有异常发生,jvm就将该异常封装成一个异常对象,在传递到相应的catch中进行处理 注意:
1)当try中代码块一旦有异常发生就直接执行相应catch中代码,try后面的代码就不会再执行 2)catch可以有多个,每个catch块中代码都可以写不同的处理方式 3)捕获异常的时候可以直接捕获父类异常,但是必须写在最后一个catch中 4)捕获异常的时候建议捕获更具体的异常,这样处理起来更加具体
try{
int n = 10 / 0;
int[] arr = new int[10];
arr[10] = 100;
}catch(ArithmeticException e){//e=0x1111
System.out.println("除数不能为0!");
System.out.println(e.getMessage());//打印异常出错的信息
// e.printStackTrace();//打印异常出错的详细信息,异常的名称,异常的信息,异常出错的位置
}catch(ArrayIndexOutOfBoundsException e){
System.err.println("索引越界啦!");//红色的字体输出
}catch(Exception e){
System.out.println("发生异常了------");
}finally{
System.out.println("finally一定会执行,不信试试!");
}
//结果
除数不能为0!
/ by zero
finally一定会执行,不信试试!
2.2 、抛出异常:throws/throw 关键字
如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。
抛出异常:
throw:运用于方法内部,用于给调用者抛出一个异常对象,和return类似,return 是返回是一个值,throw 是返回一个错误给该方法的调用者。
throws:运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。
异常转译:当位于最上层的子系统不需要关心底层的异常细节时,常见的做法是捕获原始的异常,把它转换为一个新的不同类型的异常,再抛出新的异常。
异常链:把原始的异常包装为新的异常类,从而形成多个异常的有序排列,有助于查找异常的根本原因。
注意:
通过 throws 来处理异常,并没有真正的处理异常,仅仅是让程序通过编译能够运行,想真正的处理异常还是得用 try...catch
public void deposit(double amount) throws IOException,ArithmeticException {
// Method implementation
throw new RemoteException();
}
定义异常处理时,什么时候定义try,什么时候定义throws呢?
功能内部如果出现异常,如果内部可以处理,就用try;
如果功能内部处理不了,就必须声明出来,让调用者处理。
3. 自定义异常在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。一般继承Exception 类即可。
- 所有异常都必须是 Throwable 的子类。
- 如果写一个检查性异常类,则需要继承 Exception 类。
- 如果写一个运行时异常类,那么需要继承 RuntimeException 类(推荐使用)。
class MyException extends Exception{ }
public class MyException extends RuntimeException { }
在程序中使用自定义异常类,大体可分为以下几个步骤。 (1)创建自定义异常类。 (2)在方法中通过throw关键字抛出异常对象。 (3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。 (4)在出现异常方法的调用者中捕获并处理异常。
public class MyException extends RuntimeException {
public MyException() {
super();
}
public MyException(String message) {
super(message);
}
/**
*
* @param message 当前异常的信息/原因
* @param cause 当前异常的根本原因 e.printStackTrace();
*/
public MyException(String message, Throwable cause) {
super(message, cause);
}
}
=== demo 类===
public static void main(String[] args) {
int res = div(10,0);
System.out.println(res);
}
public static int div(int a, int b) {
int res;
try {
res = a / b ;
}catch (ArithmeticException e){
e.printStackTrace();
throw new MyException("除数不能为0!", e);
}
return res;
}
1)一个catch子句捕获多个异常
Java7 改进了catch子句的语法,允许在其中指定多种异常,每个异常类型之间使用“|”来分隔。如:
public static void main(String[] args) {
int a = 10;
int b = Integer.parseInt("hello");
try {
int res = a / b;
System.out.println(res);
} catch (ArithmeticException | NumberFormatException e){
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
}
需要注意:
(1)在catch子句中声明捕获的这些异常类中,不能出现重复的类型,也不允许其中的某个异常是另外一个异常的子类,否则会出现编译错误。
(2)在catch子句中声明了多个异常类,那么异常参数的具体类型是所有这些异常类型的最小上界。
2)try-with-resources:自动资源关闭
Java7 以前对某些资源的操作是需要手动关闭,如InputStream,Writes,Sockets,Sql等,需要在finally中进行关闭资源的操作,现在不需要使用finally来保证打开的流被正确关闭,Java7 之后可采用try-with-resources方式后,不需要再次声明流的关闭。
使用try-with-resources的资源对象有:任何实现了 java.lang.AutoCloseable接口 和 java.io.Closeable接口 的对象。为了支持这个行为,所有可关闭的类将被修改为可以实现zhe这两个(可关闭的)接口之一。
如果在try语句中写入了没有实现该接口的类,会提示:
The resource type File does not implement java.lang.AutoCloseable
public class Student implements Closeable {
@Override
public void close() throws IOException {
}
}
// java 7 之前
public static void main(String[] args) {
OutputStream out = null;
try {
out = new FileOutputStream("E:/123.txt");
out.write(1);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(out != null){ // 关闭资源
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// java 7 之后
public static void main(String[] args) {
try (
// 存放在这里的资源类必须实现 java.lang.AutoCloseable接口 或者 java.io.Closeable接口
OutputStream out = new FileOutputStream("E:/123.txt");
//Student student = new Student();
){
out.write(1);
} catch (Exception e) {
e.printStackTrace();
}
}
参考文章: https://blog.csdn.net/hguisu/article/details/6155636
常见的RuntimeException异常
ends ~