Exception
a.分类:
错误 Error 合理的应用程序不应该试图捕获的严重问题。说明我们不需要处理这种问题,比如说内存溢出。
异常 Exception 合理的应用程序想要捕获的条件,说明是需要我们进行处理的。异常又分为两种异常:
(1)编译时期异常 非RuntimeException 这是我们必须要处理的异常。
(2)运行时期异常 RuntimeException 这种异常,一般我们也是不需要处理的。一般出现这样的问题,应该是我们写的代码出问题了。
b.JVM的默认处理方案:
1.程序出现了异常,如果我们没有做任何处理,jvm做出了默认的处理。
2.把异常的类名,产生的原因以及出现的位置等信息显示在了控制台。
3.并让程序从这里结束了。
c.java中我们如何处理异常呢?
A:try…catch…finally
B:throws
try…catch…finally格式
try {
可能出现问题的代码
}catch(异常类名 变量) {
针对问题的处理
如throw new Exception();
或e.PrintStackTrace();
}finally {
释放资源的代码
}
d.Java中的异常被分为两大类:
编译时异常和运行时异常。所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常
编译时异常
Java程序必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常
无需显示处理,也可以和编译时异常一样处理
e.多个异常的情况:
A:针对每个异常,给出一个处理
B:try...catch...catch...catch...
注意:
a:一旦try里面的代码有问题,就不在执行try里面的内容,和catch里面的内容依次的匹配,一旦有一个匹配,其他的不执行。
b:如果异常是平级关系,谁先谁后无所谓。
如果异常不是平级关系,子先父后。
f.在处理异常时一般有2种处理方式:
1.catch{}函数中
try {
System.out.println(a / b); // 从哪里产生异常,就会在哪里创建一个异常的对象。new
// ArithmeticException();
// 然后,拿着该异常对象,到catch里面去匹配。
}
catch (ArithmeticException e){
System.out.println("除数不能为0");
System.out.println(e.getMessage()); //输出java.lang.ArithmeticException: / by zero
System.out.println(e.toString());//输出/ by zero
e.printStackTrace();//输出java.lang.ArithmeticException: / by zero
at cn.ExceptionDemo.main(ExceptionDemo.java:13)
}
小结:
getMessage():获取异常信息,返回字符串。
toString():获取异常类名和异常信息,返回字符串。
printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
2.使用在方法中使用Throw使程序调转:
public static void main(String[] args) {
String s = "abc";
if(s.equals("abc")) {
throw new NumberFormatException();
} else {
System.out.println(s);
}
//function();
}
或
public static void show() throws ParseException, ArithmeticException,
NullPointerException {
if ("hello".equals("world")) {
throw new ParseException(null, 0);
} else {
System.out.println("over");
}
}
g.Throw与Throws的区别:
上面已经展示了Throw的用法,下面来说说Throws的用法:
Throws一般用在方法声明处:方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
public class testThrows(){
public static void function() throws NumberFormatException{
String s = "abc";
System.out.println(Double.parseDouble(s));
}
public static void main(String[] args) {
try {
function();
} catch (NumberFormatException e) {
System.err.println("非数据类型不能强制类型转换。");
//e.printStackTrace();
}
} 注:一般方法声明了Throws表示可能含有异常情况,因此在调用它时必须使用try{}catch{}语句来捕获异常否则无法编译通过。
以下比较转自https://blog.csdn.net/hjfcgt123/article/details/53349275
throw与throws的比较:
1、throws出现在方法函数头;而throw出现在函数体。
2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
3、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
编程习惯:
1.在写程序时,对可能会出现异常的部分通常要用try{...}catch{...}去捕捉它并对它进行处理;
2.用try{...}catch{...}捕捉了异常之后一定要对在catch{...}中对其进行处理,那怕是最简单的一句输出语句,或栈输入e.printStackTrace();
3.如果是捕捉IO输入输出流中的异常,一定要在try{...}catch{...}后加finally{...}把输入输出流关闭;
4.如果在函数体内用throw抛出了某种异常,最好要在函数名中加throws抛异常声明,然后交给调用它的上层函数进行处理。
h.下面单独介绍finally:
finally:被finally控制的语句体一定会执行。
应用:数据库的连接,IO操作的时候。
注意事项:在执行到finally之前jvm退出了。
final,finally和finalize的区别?
final:修饰类,修饰成员变量,修饰成员方法
修饰类,类不能被继承
修饰成员变量,变量是常量
修饰成员方法,方法不能被重写
finally:被finally控制的代码永远会执行,用于释放资源。
注意事项:就是在执行到finally之前jvm退出了。
finalize:是Object类的方法,启动垃圾回收器,用于回收垃圾。
如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后。
会执行。
前。
准确的说法:中间。
整个这个过程有三步:
1:执行到return 40;的时候,就在内存中形成了一个返回路径。
2:由于它发现还有一个finally,所以,继续执行了finally,n=50
3:finally结束后,再次回到以前的返回路径,继续。所以返回的是40
public class FinallyTest {
public static void main(String[] args) {
System.out.println(returnInt()); // 40
}
public static int returnInt() {
int n = 10;
try {
n = 20;
System.out.println(10 / 0);
n = 30;
} catch (ArithmeticException e) {
n = 40;
return n;
} finally {
n = 50;
}
}
return 0;
}
输出结果为:40。
I.自定义异常类
java API虽然提供了大多数的异常类,但是他不可能考虑到所有的情况。
所以呢,针对我们自己的特殊需求的异常,我们需要自己定义异常。
而我们要自己定义一个类,让他成为异常类,那么,它必须要继承自异常类。
继承自哪个呢?
继承自Exception
继承自RuntimeException
例:
public class MyException extends Exception {
public MyException() {
super();
}
public MyException(String message) {
super(message);
}
}