异常
概述
异常: 不正常。程序的运行结果与预想的结果不一致。
常见异常
① NullPointerException 空指针异常
② ArrayIndexOutOfBoundsException 数组角标越界异常。
③ ClassCastException 类型转换异常
④ NumberFormatException 数字格式化异常
⑤ ArithmeticException 算术异常/除0异常
⑥ ParseException 解析异常
⑦ InputMismatchException 输入比对错误异常
异常体系
Throwable
|————— Error 合理的应用程序不应该试图捕获的严重问题
|—————-Exception 合理的应用程序想要捕获的条件
|————-编译期异常:(除了RuntimeException) 编译时,如果不处理,程序就不能执行
|————-运行期异常:(RuntimeException):在编译期可以不处理,运行期处理。
异常处理的好处
提高程序的健壮性。
异常的处理机制
原则:
谁调用谁处理
处理过程:
jvm一旦遇到异常,会将异常根据不同的特征封装成异常对象,并且返回给调用者,如果调用者处理
不了,向上继续返回,直到返回到main方法,如果main中也处理不了。就返回到jvm。jvm会将异常打印在控制台上输出。
异常的处理方式:
1.异常的声明:俗称 抛出异常:
[权限修饰符][修饰符][返回值类型] 方法名称(参数列表) throws 异常名称1,异常名称2{}
2.异常的捕获:
try{
可能会发生异常的代码
}catch(异常的数据类型 异常的名称){
处理异常的代码
}finally{
无论是否执行try 或catch,最终都会执行。
}
try-catch-finally书写格式
格式一: 多catch try- catch- finally
try{
可能发生异常的代码
}catch(异常的数据类型 异常的名称){
处理异常的代码
}catch(异常的数据类型 异常的名称){
处理异常的代码
}finally{
}
注意:
如果catch块中异常有子父类的关系,子类在上 父类在下。
格式二:多catch try- catch
try{
}catch(){
}
格式三: try - finally
try{
}finally{
}
注意:
1》 try块中放置可能会发生异常的代码,该代码执行到发生异常为止,该位置下的try块中的代
码不再执行。
2》转而执行catch中的代码,前提是catch中可以捕获到该异常。
3》 无论执行了try 还是 catch块 最终都会执行 finally。
4》如果try块中没有发生异常,只执行try后,最终也会执行finally。
代码
package com.demo;
/**
1.格式:
try{
}catch(异常的数据类型 异常的名称){
}finally
注意:
1》 try块中放置可能会发生异常的代码,该代码执行到发生异常为止,该位置下的try块中的代 码不再执行。
2》转而执行catch中的代码,前提是catch中可以捕获到该异常。
3》 无论执行了try 还是 catch块 最终都会执行 finally。
4》如果try块中没有发生异常,只执行try后,最终也会执行finally。
2.格式三: try - finally
try{
}finally{ }
*/
public class 异常的捕获执行顺序 {
public static void main(String[] args) {
/* try{
System.out.println("这是异常之前的代码。。。1");
int i= 5/1;
System.out.println("这是异常之后的代码。。。。2");
}catch(Exception e ){
System.out.println("这是捕获后处理异常的代码。。。3");
}finally {
System.out.println("这是无论是try或catch执行后,都会执行的代码。。。4"); }*/
// 格式三:
try{
System.out.println("这是try中的代码。。");
int i = 5/0;
}finally{
System.out.println("这是finally中的代码。。。");
}
}
}
Return返回值问题
原则上不建议在finally中添加return,一旦添加,由于无论执行try还是catch,都最终会执finally,最终导致finally中的return先执行。
代码
package com.demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
1.return 在try catch finally中同时存在时,return返回的问题
注意:
原则上不建议在finally中添加return,一旦添加,由于无论执行try还是catch,都最终会执行finally,最终导致finally中的return先执行。
*/
public class Return返回值问题 {
public static void main(String[] args) /*throws ParseException*/ {
System.out.println(fun());
SimpleDateFormat sf = new SimpleDateFormat();
try{
sf.parse("111");
}catch (ParseException e){
}
}
public static int fun() {
try{
int i = 5/0;
return 1;
}catch (Exception e){
return 2;
}finally {
return 3;
}
}
}
异常对象的创建
1.异常对象的创建:
① 异常的发生可以阻止程序继续执行。
② 模拟jvm抛出异常对象:
格式:
throw new 异常对象(异常信息)
代码
package com.demo;
import java.util.Scanner;
/**
1.异常对象的创建:
① 异常的发生可以阻止程序继续执行。
② 模拟jvm抛出异常对象:
格式:
throw new 异常对象(异常信息)
*/
public class 异常对象的创建 {
public static void main(String[] args) {
/* A a = new A();
a.fun();
System.out.println("======================2");*/
BankAccount ba = new BankAccount();
ba.withdraw();
}
}
class A{
public void fun(){
int i = 5;
i /= 0;
System.out.println("================1");
}
}
class BankAccount{
double balance = 1000;
public void withdraw(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入取款金额:");
double money = sc.nextDouble();
if (balance-money >=0){
balance -= money;
}else{
// System.out.println("余额不足。。。"+5/0);
// throw 模拟jvm创建并抛出异常对象给调用者
throw new RuntimeException("余额不足");
}System.out.println(balance +"=========================");
}
}
自定义异常
继承Exception 或RuntimeException
常用异常方法
异常的常用方法:
① getMessage() 获取异常的详细消息字符串
② printStackTrace() 打印堆栈信息
代码
package demo1;
import java.util.Scanner;
/**
1.异常对象的创建:
① 异常的发生可以阻止程序继续执行。
② 模拟jvm抛出异常对象:
格式:
throw new 异常对象(异常信息)
2.异常的处理方式:
① 异常的声明:throws
② 异常的捕获 : try-catch-finally
3.异常的常用方法:
① getMessage() 获取异常的详细消息字符串
② printStackTrace() 打印堆栈信息
*/
public class 异常对象的创建 {
public static void main(String[] args) {
/* A a = new A();
a.fun();
System.out.println("======================2");*/
BankAccount ba = new BankAccount();
//异常的捕获
while (true) {
try {
ba.withdraw(); break;
} catch (WithDrawException e) {
// System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
class A{
public void fun(){
int i = 5;
i /= 0;
System.out.println("================1");
}
}
class BankAccount{
double balance = 1000;
public void withdraw() throws WithDrawException{//异常的声明
Scanner sc = new Scanner(System.in);
System.out.println("请输入取款金额:");
double money = sc.nextDouble();
if (balance-money >=0){
balance -= money;
}else{
// System.out.println("余额不足。。。"+5/0);
// throw 模拟jvm创建并抛出异常对象给调用者
// throw new RuntimeException("余额不足");
throw new WithDrawException("余额不足");
}
System.out.println(balance +"=========================");
}
}
//继承Exception 或RuntimeException
class WithDrawException extends Exception{
public WithDrawException(String msg){
super(msg);
}
}
异常的总结
1.try-catch-finally throw throws
异常的处理机制: 谁调用谁处理
异常的处理方式:
① 异常的声明 throws
② 异常的捕获 try-catch-finally 三种 try-catch try-catch-finally try -finally
2.throw 与throws的区别?
① throw 表示模拟jvm抛出异常对象。在方法中 创建异常对象时,使用的。
② throws 表示异常的处理方式,在方法参数的后面 ,表明该方法可能会发生哪种异常。
3.return 体系 方法