java学习之异常
程序出现的不正常的情况叫异常
异常体系
Throwable
|–Error 严重问题,我们不处理。(例如内存溢出)
|–Exception
|–RuntimeException 运行期异常,运行过程中出现的错误,我们需要修正代码,
|–非RuntimeException 编译期异常,必须处理的,否则程序编译不通过,不能运行
编译时异常和运行时异常的区别
- 编译期异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译
- 运行期异常:无需显示处理,也可以和编译时异常一样处理
异常的处理
try…catch…finally
格式
- try里面的代码越少越好
- catch里面必须有内容,哪怕是给出一个简单的提示
try {
可能出现问题的代码;
}catch(异常名 变量) {
针对问题的处理;
}finally {
释放资源;
}
多个异常
注意事项:
-
1:能明确的尽量明确,不要用大的来处理。
-
2:平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。
public static void method4() {
int a = 10;
int b = 0;
int[] arr = { 1, 2, 3 };
// 爷爷在最后
try {
System.out.println(a / b);
System.out.println(arr[3]);
System.out.println("这里出现了一个异常,你不太清楚是谁,该怎么办呢?");
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("你访问了不该的访问的索引");
} catch (Exception e) {
System.out.println("出问题了");
}
System.out.println("over");
}
JDK7出现了一个新的异常处理方案:
try{
catch(异常名1 | 异常名2 | … 变量 ) {
…
}
注意:这个方法虽然简洁,但是也不够好。
A:多种错误的处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理)
B:多个异常间必须是平级关系。
方法
public String getMessage():异常的消息字符串
public String toString():返回异常的简单信息描述
此对象的类的 name(全路径名) ": "(冒号和一个空格) 调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。(默认)
public class ExceptionDemo {
public static void main(String[] args) {
String s = "2014-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date d = sdf.parse(s); // 创建了一个ParseException对象,然后抛出去,和catch里面进行匹配
System.out.println(d);
} catch (ParseException e) { // ParseException e = new ParseException();
// ParseException
// e.printStackTrace();
// getMessage()
// System.out.println(e.getMessage());
// Unparseable date: "2014-11-20"
// toString()
// System.out.println(e.toString());
// java.text.ParseException: Unparseable date: "2014-11-20"
e.printStackTrace();
//跳转到某个指定的页面(index.html)
}
System.out.println("over");
}
}
finally
finally:被finally控制的语句体一定会执行
注意:如果在执行到finally之前jvm退出了,就不能执行了。
格式
try…catch…finally…
用于释放资源,在IO流操作和数据库操作中会见到
throws 抛出
有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。
或者说,我处理不了,我就不处理了。
为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
格式
throws 异常类名
注意:这个格式必须跟在方法的括号后面。
- 编译期异常抛出,将来调用者必须处理。
- 运行期异常抛出,将来调用可以不用处理。
public class ExceptionDemo {
public static void main(String[] args) {
System.out.println("今天天气很好");
try {
method();
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("但是就是不该有雾霾");
method2();
}
// 运行期异常的抛出
public static void method2() throws ArithmeticException {
int a = 10;
int b = 0;
System.out.println(a / b);
}
// 编译期异常的抛出
// 在方法声明上抛出,是为了告诉调用者,你注意了,我有问题。
public static void method() throws ParseException {
String s = "2014-11-20";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(s);
System.out.println(d);
}
}
和throw的区别(面试题)
- throws
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
public class ExceptionDemo {
public static void main(String[] args) {
String date = "2021-10-02";
try {
mentod(date);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("over");
}
public static void mentod(String date) throws ParseException {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH");
Date d = sd.parse(date);
System.out.println(d);
}
}
- throw
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常
public class ExceptionDemo {
public static void main(String[] args) {
try {
mentod();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void mentod() throws Exception {
int a = 0;
if(a == 0){
throw new Exception();
}else{
System.out.println("没问题");
}
}
}
自定义异常
介绍
java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。
而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类是一个异常类,就必须继承自Exception或者RuntimeException
public class MyException extends Exception {
public MyException() {
}
public MyException(String message) {
super(message);
}
}
注意事项
- 子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
- 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
- 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
class Fu {
public void show() throws Exception {
}
public void method() {
}
}
class Zi extends Fu {
@Override
public void show() throws ArithmeticException {
}