异常概述:
异常:异常就是Java程序运行过程中出现的错误(通常有不同严重程度)。
异常由来:问题也是现实生活中的一个具体事务,也可以通过Java形式对其进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。
常见异常:数组越界异常,空指针异常。
虚拟机默认处理: ★将异常信息输出
名称,原因,出错信息,位置等信息输出在控制台
★退出当前程序
|
try {
}catch (){
}
finally{
}
|
变形格式:
1 只有try catch 不含finally 注意:一旦try中出了问题,就会抛出去跟catch进行匹配,如有匹配,则执行catch内语句,然后退出try内的语句。
2 有多个catch
|
异常捕获注意事项:
★一个异常的情况
异常尽量明确()
★捕获多个异常的情况:
如果有多个 catch 语句,则平级关系异常前后顺序无所谓,但是如果出现了父子关系的异常,则子必须在父之前。
编译时异常 VS 运行时异常
编译时异常,必须在编译前处理,否则无法通过编译;运行时异常——runtime exception,运行时处理
Throwable常见方法:
getMessage()
toString()
|
printStackTrace()
…
|
声明异常:
★对于可能发生可检查异常的方法或构造函数,可以在方法头部分使用throws语句声明可能可发生的异常列表
<返回类型> <方法签名> throws <异常列表>
★异常列表可以包括一个或多个异常类
public void methodA() throws ExceptionA { … }
抛出异常:
★在方法体中可以通过throw语句抛出异常
throw <异常类的对象>
★如果抛出的异常对象属于可检查的异常,则必须与方法的异常列表中的异常兼容
public void replaceValue(String name, Object value)
throws NoSuchAttributeException
{
Attr attr=find(name);
if(attr==null)
throw new NoSuchAttributeException(name);
attr.setValue(value);
}
|
throw vs throws:
throws
♥ 用在方法后,跟异常类名
♥ 可跟多个异常类名,由方法调用者处理
♥ 表示可能抛出这些异常,但是不是一定会抛
|
throw
♥ 用在方法体内,后跟异常对象名
♥ 只能抛出一个异常对象名
♥ 表示抛出异常,由方法体内的语句产生
♥ 执行throw 语句必然抛出某种异常
|
异常处理原则:
原则:如内部功能可以处理该异常,用try,否则用throw
二者区别:throws 抛给调用者,如果调用者没有处理则会引发程序退出
finally:
特点:被finally控制的语句块一定会执行(不管try内是否有抛出异常);特殊情况,走到finally之前JVM退出了
Finally作用:用于释放资源
Finally相关面试题
如果catch里有return语句,请问finally里面的代码还会执行吗?请问是在return前还是return后? 会,在return前;准确的说,应该是在中间。不return,程序还能往下接着执行
自定义异常:
引入:为何要有自定义异常
自定义异常:继承自Exception,继承自RuntimeException
package com.java.exception;
public class TestMain {
public static void main(String[] args) {
int[] array=new int[5];
try{
System.out.println("TestMain.main()"+array[5]); //产生异常,程序在此结束
int a=1/0;
array=null;
array[1]=10;
}
catch( ArrayIndexOutOfBoundsException e){ //捕获异常也可以让该异常的父类去捕获
// catch(Exception e)
String message=e.getMessage();
String etoString=e.toString();
e.printStackTrace(); //可以将异常产生位置的调用栈打印到命令行
System.out.println("error index is : "+message);
System.out.println("error String is : "+etoString);
}catch (ArithmeticException e){
String message=e.getMessage();
System.out.println("ArithmeticException is : "+message);
}catch (NullPointerException e){
String message = e.getMessage();
System.out.println("NullPointerException is :" +message);
}
|
/*
catch(ArrayIndexOutOfBoundsException|ArithmeticException|NullPointerException e){
String message = e.getMessage();
System.out.println("Exception is :" +message);
}
*/
/*
try{
int a=1/0;
}catch(ArithmeticException e){
String message = e.getMessage();
System.out.println("ArithmeticException is :" +message);
}
try{
array=null;
array[1]=10;
}catch(NullPointerException e){
String message = e.getMessage();
System.out.println("NullPointerException is :" +message);
}
*/
|
try{
test1(0);
}catch(FileNotFoundException e){
e.printStackTrace();
}
public static void test1(int i) throws FileNotFoundException{
//如果方法里面throw异常但是没有catch处理,就要在方法头throws异常,调用的时时候处理这个异常;
if(0==i){
throw new FileNotFoundException();
}
}
|
test1(0); public static void test1(int i){
//如果方法里面throw异常同时catch处理完了异常,就不用在方法头throws异常并处理;
if(0==i){
try{
throw new FileNotFoundException();
} catch(FileNotFoundException e){
e.printStackTrace();
}
}
}
|
package com.java.exception;
public class InputInvalidException extends Exception {
public InputInvalidException(String message){
super(message);
}
}
|
package com.java.exception;
import java.util.Scanner;
public class Demo {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int i=scanner.nextInt();
Teacher teacher=new Teacher();
try{
teacher.score(i);
}catch(InputInvalidException e){
String msString =e.getMessage(); //获取父类的message
System.out.println("异常发生! "+msString);
}
}
}
class Teacher{
public String score(int i) throws InputInvalidException{
if(i<0||i>100){
throw new InputInvalidException("这里是因为输入范围非法");
}
String ret="";
if(i>90){
ret="优秀";
}
return ret;
}
}
|