异常
异常体系里:没有接口,全都是类。
Exception将异常分为运行时异常(RuntimeException)和编译期异常
- 运行时异常:IDE工具不会提示你处理,不显示处理,也可以和编译时异常一样处理,如ArithmeticException,IndexOutOfBoundsException
- 编译期异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译,如Thread.sleep(1000);时的InterruptedException(当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常)
Throwable
- 错误:Error 我们不处理。这种问题一般都是很严重的,比如说内存溢出。
- 异常:Exception
- 编译期问题:不是RuntimeException的异常 必须进行处理的,因为你不处理,编译就不能通过。
- 运行期问题:RuntimeException 这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。
默认处理
把异常的名称,原因及出现的问题等信息输出在控制台。
同时会结束程序。
寄几处理
程序中断运行,处理后继续运行
try...catch...finally
try里面的代码越少越好,会影响执行的效率
catch里面必须有内容,不然只是隐藏了问题,没有意义
能明确的尽量明确,不要用大的来处理
-
平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。会报错,后面的无法执行
//一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配 //一旦有匹配的,就执行catch里面的处理,try中异常后面的不再执行, //如果有finally,就执行finally里的语句 //然后结束了try...catch,继续执行try...catch后面的语句 try{ ... }catch(异常类名 变量名) { //依次比较 ... } catch(异常类名 变量名) { ... } ... }finally{ } // JDK7的处理方案 //处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理) //多个异常间必须是平级关系。如果有父子关系就报错,无论父异常在前在后 try { ... } catch (ArithmeticException | ArrayIndexOutOfBoundsException | ...e ) { ... }
catch
catch中:Throwable的对象e执行子类的引用对象(多态)
Throwable的方法:
public String getMessage():异常的消息字符串
public String toString():返回异常的简单信息描述
此对象的类的 name(全路径名)": "(冒号和一个空格)
调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)
printStackTrace() (最常用)
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。
try...catch...finally的格式
- try...catch...finally
- try...catch
- try...catch...catch...
- try...catch...catch...finally
- try...finally
throws
功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出
public void exceptionTest() throws InterruptedException,ArithmeticException.... {
Thread.sleep(1000);
}
throws和throw
throws
- 用在方法声明后面,跟的是异常类名
- 可以跟多个异常类名,用逗号隔开
- 表示抛出异常,由该方法的调用者来处理
- throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
- 用在方法体内,跟的是异常对象名
- 只能抛出一个异常对象名
- 表示抛出异常,由方法体内的语句处理
- throw则是抛出了异常,执行throw则一定抛出了某种异常
finally
- 被finally控制的语句体一定会执行
- 除非服务器炸了,执行到finally之前jvm退出了(比如System.exit(0))
- 用于释放资源
final,finally和finalize
- final:最终的意思,可以修饰类,成员变量,成员方法
- 修饰类,类不能被继承
- 修饰变量,变量是常量
- 修饰方法,方法不能被重写
- finally:是异常处理的一部分,用于释放资源。
- 一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
- finalize:是Object类的一个方法,用于垃圾回收
try...catch...finally...执行
//有一些处理的抛出
public class test {
public static void main(String[] args) {
try {
System.out.println("1");//执行
int i = 1/0;
System.out.println(2);//不执行
} catch (Exception e) {
System.out.println(3);
throw new RuntimeException(); //相当于抛出
}finally {
System.out.println(4); //执行
}
System.out.println(5); //不会执行
}
}
//
public class test {
public static void main(String[] args) {
try {
System.out.println("1");//执行
int i = 1/0;
System.out.println(2);//不执行
} catch (Exception e) {
System.out.println(3);
}finally {
System.out.println(4); //执行
}
System.out.println(5); //执行
}
}
如果catch里面有return语句,请问finally里面的代码还会执行吗?
会执行,在return之前执行
public int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
/*
* return a在程序执行到这一步的时候,这里不是return a而是return 30;这个返回路径就形成了。
* 但是呢,它发现后面还有finally,所以继续执行finally的内容,a=40
* 再次回到以前的返回路径,继续走return 30;
*/
} finally {
a = 40;//如果这样结果就是40了。
}
return a; //这个没有意义
}
//------------------------------------------
public int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
return a;
} finally {
a = 40;
return a;
}
}
//返回40
自定义异常
public class ScoreOutOfLimitException extends Exception{ //继承Exception或RuntimeException 决定是编译时异常或运行时异常
public ScoreOutOfLimitException() {
super();
}
public ScoreOutOfLimitException(String message) {
super(message);
}
}
//--------------------------------------------------
public class Student {
private double score;
public void add(double s) throws ScoreOutOfLimitException { //判断方法中一般抛出
if(s < 0 || s > 100) {
throw new ScoreOutOfLimitException("分数越界了"); //提示信息,有参构造需要重写构造方法
}else {
this.score = s;
}
}
}
//----------------------------------------------------
public class MyMain {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入分数");
int i = sc.nextInt();
try {
new Student().add(i);
} catch (ScoreOutOfLimitException e) {
e.printStackTrace();
}
}
}
//--------------------------------------------------
请输入分数
120
com.leex.Mythrow.ScoreOutOfLimitException: 分数越界了
at com.leex.Mythrow.Student.add(Student.java:10)
at com.leex.Mythrow.MyMain.main(MyMain.java:11)
异常与继承
- 子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
- 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
- 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws