禹娜(异常)
异常
什么是异常?
异常是指程序在编译或是在运行时发生的不寻常的事情。
发生异常后应该怎么办?
如果一个程序发生异常,那么这个程序就无法正常运行了。就会导致程序强行终止运行。这时候我们就要去捕获这个异常。只要我们把这个异常捕获了,程序中就没有异常了,这时候程序就可以正常运行了。
异常的体系结构
Throwable类
Throwable类是异常体系结构的父类。Throwable类的父类是Object。
在Throwable分为Error(错误) 和Exception(异常)。
Error类
Error是指无法通过开发人员编写程序能够解决的异常叫做Error。
例如:内存的溢出,动态链接失败(加载dll文件),虚拟机错误。
Exception类
Exception是所有异常类的父类,这里的异常时指能够通过编写程序处理的异常。
Exception类有两套子类,一套是运行时异常,一套是编辑时异常。规定编辑时异常必须捕获,如果不捕获会导致程序无法编译,就不能运行了。
例如
public class Demo1{
public static void main(String[] args){
class.forName("java.lang.String");//编译时异常
}
}
解决方法
public class Demo1{
public static void main (String[] args){
try{
class.forName("java.lang.String");
}catch(classNotFoundException e){
e.printStackTrace();
}
}
}
RuntimeException
RuntimeException类是所有运行时异常的父类。
如何捕获异常
Java中用try,catch,finally,throw,throws这五个关键字捕获异常。其中try,catch,finally为一组专门处理异常的方式,其中throw,throws为一组专门处理异常的方式。
try catch finally异常处理
3种使用结构
1.
try{
}catch(Exception e){
}
2.
try{
}catch(Exception e){
}finally{
}
3.
try{
}finally{
}
注意:
1.try中用于包裹住可能发生异常的代码。
2.catch用于捕获异常,并对异常进行处理。
3.finally用于回收资源。
4.try与catch组合时,一个try可以与多个catch组合,但是只能有一个try。
5.try与finally组合时,一个try只能与一个finally组合 ,且try与finally都只能有一个
6.try不能单独使用,catch不能单独使用,finally不能单独使用,catch和finally不能组合使用。
例1
不捕获异常
public class Demo1 {
public static void main(String[] args) {
int i=1,j=0,res;
System.out.println("begin");
res = i/j;
System.out.println("end");
}
}
使用try和catch捕获异常
public class Demo1 {
public static void main(String[] args) {
try {
int i=1,j=0,res;
System.out.println("begin");
res=i/j;//抛出异常
System.out.println("end");
}catch(Exception e){//异常捕获
System.out.println("catched");
e.printStackTrace();
}
System.out.println("over");
}
}
输出
begin
catched
java.lang.ArithmeticException: / by zero
at day5.Demo1.main(Demo1.java:8)
over
分析:1.try中放了可能发生异常的代码。
2,。如果try发生了异常,那么程序就会立刻被catch捕获。捕获之后异常就没有 了。所有的程序就可以正常运行了。
3.异常发生后,程序进入到catch,导致从异常发生位置开始到catch位置之间的代码无法运行。
4.当try中没有发生异常时,程序不会进入到catch中执行。
例2 finally
package day5;
public class Demo2 {
public static void main(String[] args) {
try {
int i=1,j=0,res;
System.out.println("begin");
res=i/j;
System.out.println("end");
}catch(ArithmeticException e) {
System.out.println("catch");
e.printStackTrace();
}finally {
System.out.println("fianlly");
}
System.out.println("over");
}
}
输出
begin
catch
java.lang.ArithmeticException: / by zero
at day5.Demo2.main(Demo2.java:8)
fianlly
over
注意:
当try中有finally时,finally是必须要执行的,遇到System.exit()时退出、
如果没有发生异常,执行顺序是try-finally
如果发生了异常,执行顺序是try-catch-finally
例3
package day5;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Demo3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try {
System.out.println("计算开始");
int i, j, res;
System.out.println("请输入被除数");
i = input.nextInt();
System.out.println("请输入除数");
j = input.nextInt();
res = i / j;
System.out.println(i + "/" + j + "=" + res);
System.out.println("计算结束");
} catch (InputMismatchException e) {
System.out.println("除数和被除数必须都是整数");
} catch (ArithmeticException e) {
System.out.println("除数不能为零");
} catch (Exception e) {
System.out.println("其他异常" + e.getMessage());
} finally {
System.out.println("感谢使用本程序");
}
System.out.println("程序结束");
}
}
注意:一个try可以配置多个catch,但是多个catch是有先后顺序的,必须把子类的catch写在前面。把父类的catch写在后面,并列的catch没有先后顺序。
throw,throws异常处理
throw和throws配合是一套处理异常的方式。两者要配合使用。
Throws
用于定义在方法的声明后面,表示该方法可能会抛出的异常,并告诉主调方法需要处理该方法抛出的异常。
Throw
Throw用在方法内部,后面紧跟一个异常对象,表示要抛出这个异常。
用法1
被调方法不处理异常,直接抛给主调方法
package day5;
public class Demo4 {
public static void main(String[] args) {
try {
divide();
}catch(ArithmeticException e) {
e.printStackTrace();
}
}
private static void divide() throws ArithmeticException {
System.out.println("start");
int i=1,j=0;
int res=i/j;
System.out.println("over");
}
}
输出
start
java.lang.ArithmeticException: / by zero
at day5.Demo4.divide(Demo4.java:15)
at day5.Demo4.main(Demo4.java:6)
分析:main是主调函数。
divide是被调方法,背调方法内部发生异常时,被调方法没有处理异常,而是将异常抛给主调方法,让主调方法处理异常。
用法二
被调方法抓住异常后再次抛出该主调方法
package day5;
public class Demo5 {
public static void main(String[] args) {
try {
divide();
}catch(ArithmeticException e) {
e.printStackTrace();
}
}
private static void divide() throws ArithmeticException{
try {
System.out.println("start");
int i=1,j=0;
int res = i/j;
System.out.println("over");
}catch(Exception e) {
ArithmeticException ex = new ArithmeticException("除零异常");
throw ex;
}
}
}
输出
start
java.lang.ArithmeticException: 除零异常
at day5.Demo5.divide(Demo5.java:20)
at day5.Demo5.main(Demo5.java:6)
分析:被调方法先自己处理异常,在抛出异常该主调方法
自定义异常
为什么要自定义异常
Java关于异常提供了很多API,如果这些异常API不能满足你的需要,就可以自己定义异常类,用于满足自己的业务需要。
自定义异常的步骤
第一步:定义异常类,继承Exception或者RuntimeException
继承Exception表示自定义编译时异常。
继承RuntimeException表示自定义运行时异常。
第二步:设置异常的描述信息
在Throwable类中定义了描述异常信息的属性,名字是message。可以将自定义异常的描述存储在该属性中。通过构造函数可将异常描述信息传递到throwable中赋值给message属性。
异常的相关方法
getMesage():获取异常描述信息
printStackTrace():输出异常的堆栈信息
方法可变参数
什么是方法可变参数
方法可变参数是指方法形参的个数可以变化,个数可以为0,或者n个。
如何定义方法可变参数
public double area(int ...param){
}
方法可变参数的规则
规则1:一个方法只能有一个可变参数。
规则2:如果一个方法有多个参数,那么可变参数必须定义在最后
规则3:方法可变参数本质上是一个数组,因此可变参数可以被当作数组来使用。
方法可变参数的调用
调用方法1:不传入参数
调用方法2:传入多个离散值
调用方法3:传入数组对象
例:
Public static void area(int ...c) {
if(c!=null && c.length>0) {
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
}
近期评论