Java异常
1.异常描述
异常:对问题的描述,将问题对象进行封装
异常体系:
Throwable
|--Error
|--Exception
|--RuntimeException
---------------------------------------
异常体系:
Throwable
|--Error
|--Exception
|--RuntimeException
---------------------------------------
异常体的特点:
异常体系中的所有类以及建立的对象都具有可抛性
也就是可以被throws 和 throw 关键字 操作
throws 和throw 的特点
throw 定义在函数内,用于抛出异常对象
throws 定义在函数上,用于抛出异常类,可以抛出多个,用逗号隔开
当函数内容有throw 抛出异常对象,并未进行try处理,必须在函数上声明,否则编译失败
注意:Exception中有一个特殊的子类异常,RuntimeException运行时异常。
异常体系中的所有类以及建立的对象都具有可抛性
也就是可以被throws 和 throw 关键字 操作
throws 和throw 的特点
throw 定义在函数内,用于抛出异常对象
throws 定义在函数上,用于抛出异常类,可以抛出多个,用逗号隔开
当函数内容有throw 抛出异常对象,并未进行try处理,必须在函数上声明,否则编译失败
注意:Exception中有一个特殊的子类异常,RuntimeException运行时异常。
如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。
如果函数上抛出该异常,调用者可以不用进行处理,编译一样通过。
之所以不用再函数声明,是因为不需要调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,
希望停止运行后,对代码进行修正。
声明:如果函数声明了异常,调用者需要进行处理。处理方式:可抛 可 try
异常有两种:
编译时异常被检测异常
该异常在编译时如果没有处理(没有抛出也没有try)
则编译失败,
声明:如果函数声明了异常,调用者需要进行处理。处理方式:可抛 可 try
异常有两种:
编译时异常被检测异常
该异常在编译时如果没有处理(没有抛出也没有try)
则编译失败,
运行时异常,编译时不检测;(RuntimeException以及其子类)
在编译时不需要处理,编译器不检查
该异常发生,建议不处理,让程序停止,对代码进行修正
---------------------------------------
在编译时不需要处理,编译器不检查
该异常发生,建议不处理,让程序停止,对代码进行修正
---------------------------------------
异常处理语句:
try{
需要被检查的代码
}
catch (Exception e){
处理异常的代码
}
finally
{
一定会执行的代码
}
三种结合形式:
1:try{
}catch(Exception e){
}
try{
需要被检查的代码
}
catch (Exception e){
处理异常的代码
}
finally
{
一定会执行的代码
}
三种结合形式:
1:try{
}catch(Exception e){
}
2:try{
}catch(Exception e){
}finally{
}
3:try{
}finally{
}
注意:finally 通常定义关闭资源代码,因为资源必须释放
}catch(Exception e){
}finally{
}
3:try{
}finally{
}
注意:finally 通常定义关闭资源代码,因为资源必须释放
finally 一种情况不好执行:System.exit(0);
---------------------------------------
自定义异常:
定义类继承Exception或者RuntimeException
1:为了让该类具有可抛性
2:让该类具备操作异常的共性方法
---------------------------------------
自定义异常:
定义类继承Exception或者RuntimeException
1:为了让该类具有可抛性
2:让该类具备操作异常的共性方法
当要定义自定义异常的信息时,可以使用父类已经定义好的功能
异常信息传递给父类的构造方法
class MyException extends Exception{
MyException(String msg){
super(msg);
}
---------------------------------------
异常的好处:
将问题封装成对象
将正常流程代码和问题处理代码分离,方便阅读
异常的处理原则:
1:try 或者 throws
2:调用到抛出异常的功能时,抛出几个,就处理几个
一个try 对应多个catch
3:多个catch 父类的catch 放在下面
4:catch 内需要定义针对性的处理方式,不要简单的
输出语句,也不要不谢
5:当捕获到的异常,本功能处理不了时,可以继续在
catch 抛出,即:
try{
try new AException();
}catch (AException e)
{
throw e;
}
将正常流程代码和问题处理代码分离,方便阅读
异常的处理原则:
1:try 或者 throws
2:调用到抛出异常的功能时,抛出几个,就处理几个
一个try 对应多个catch
3:多个catch 父类的catch 放在下面
4:catch 内需要定义针对性的处理方式,不要简单的
输出语句,也不要不谢
5:当捕获到的异常,本功能处理不了时,可以继续在
catch 抛出,即:
try{
try new AException();
}catch (AException e)
{
throw e;
}
如果该异常处理不了,但并不属于该功能出现的异常
可以将异常转换后,再抛出和该功能相关的异常
或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,
让调用者知道,并处理。也可以捕获异常处理后,转换新的异常。
try{
throw new AException();
}catch( AException e){
throw new BException();
}
比如 :汇款
try{
throw new AException();
}catch( AException e){
throw new BException();
}
比如 :汇款
异常的主要事项:
在子父类覆盖时:
在子父类覆盖时:
1:
子类抛出 的异常必须是父类的异常的子类或者子集
2:如果父类或者接口没有异常抛出,子类覆盖出现异常,只能try不能抛throws
当所调用的方法可能抛出异常时,调用者必须对其捕捉(try)或者声明(throws)以便抛出。
2.多catch
package day09;
/*
*
* 异常:就是程序在运行时出现的不正常情况
* 异常由来:问题也是现实生活中一个具体的事物,也可以通过java类的形式进行描述。并封装成对象。
* <span style="white-space:pre"> </span> 其实就是java对不正常情况进行描述后的对象体现
* 问题划分: 两种 严重和不严重的
* 严重的 使用 Error 类描述,一般不编写针对性的代码进行处理
* 不严重的使用 Exception 描述,一般需要编写针对性的代码进行处理
* Throwable
* |--Error
* |--Exception
* java 提供了特有语句进行处理
*
* try{
* 需要被检查的代码;
* }catch(异常类 变量){
* 处理异常 的代码(处理方式)
* }finally{
* 一定会执行的代码
* }
*
* 3 对捕获的异常对象进行常见的方法操作:
* String getMessage();
*
* 对多异常进行处理:
* 1:声明异常时,建议声明更为具体的异常,这样可以处理的更具体
* 2:声明几个异常,就对应几个catch块
* 若多个catch块异常出现继承关系,父类异常放在下边处理
* 不要定义多余的catch块,
* 建立catch处理时,catch中要定义具体的处理方式,
* 不要简单定义e.printStackTrace();
* 也不要简单打印
* */
public class ExceptionDemo {
public static void main(String[] args) {
Demo demo=new Demo();
try {
int x=demo.div(4, 0);//ArithmeticException
System.out.println("x= "+x);
} catch (ArithmeticException e) {
System.out.println("除以 0 了");
e.printStackTrace();//异常名称,异常信息,异常出现的位置
//jvm 默认的异常处理就是调用 printStackTrace()方法,打印异常在堆栈中的跟踪信息
System.out.println(e.toString());//异常名称,异常信息,
System.out.println(e.getMessage());//异常信息,
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("--数组引用越界");
e.printStackTrace();//异常名称,异常信息,异常出现的位置
//jvm 默认的异常处理就是调用 printStackTrace()方法
System.out.println(e.toString());//异常名称,异常信息,
System.out.println(e.getMessage());//异常信息,
}catch ( Exception e) {
System.out.println("--数组引用越界");
e.printStackTrace();//异常名称,异常信息,异常出现的位置
//jvm 默认的异常处理就是调用 printStackTrace()方法
System.out.println(e.toString());//异常名称,异常信息,
System.out.println(e.getMessage());//异常信息,
}
}
}
class Demo{
int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException <strong><span style="color:#ff0000;">//通过throws关键字声明该功能可能会出现问题</span></strong>
<span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span><span style="color:#ff0000;"><strong>//调用者要么try,要么throws</strong></span>
int [] arr=new int[0];
System.out.println(arr[4]);
return a/b;
}
}
3自定义异常(自定义类继承Exception)
继承Exception的原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。它们都具备可抛性。
这个可抛性是Throwable这个体系中独有特点。
只有这个体系中的类和对象才能被throw 和 throws操作。
自定义异常时,如果该异常发生,无法继续进行运算,就让该异常继承RuntimeException。
package day09;
/*
* 因为项目中会出现特有的问题
* 而这些问题没有被java描述并封装对象
* 对于特有的问题 可以按照java思想 进行
* 将特有问题,自定义异常封装
*
* 自定义 异常
* 需求:在本程序中 除数不可以为负数 -1,视为不可以运算
* 当在函数内部出现 throw 抛出异常对象,那么 必须给出对应的处理动作
* 1:在内部 try-catch 处理
* 2:在函数后声明,让调用者处理
* 一般情况下,函数内 出现异常,函数上声明
*
* 如何定义呢:
* 因为父类中已经把异常信息的操作都完成了
* 所以子类只要在构造时,通过super 语句将异常信息传递给父类
* 那么就可以直接通过getMessage 方法获取自定义的异常信息
*
* 异常体系特点:因为异常类和异常对象都被抛出
* 他们具有可抛性
* 可抛性是Throwabale体系的独有特点
* 只有这个体系中的类和对象才可以被Throws 和 Throw 操作
* Throws 和 Throw 的区别:
* throws 使用在函数上
* throw 使用在函数内
*
* throws 后面跟异常类,可以跟多个,用逗号隔开
* throw 后跟异常对象
* */
public class ExceptionDemo3 {
public static void main(String[] args) {
Demo3 demo=new Demo3();
try {
demo.div(4, -1);
} catch (FushuException3 e) {
System.out.println(e.toString());//toString 调用getMessage方法
System.out.println(e.getMessage());
}
}
}
class Demo3{
int div(int a,int b) throws FushuException3{
//通过throws关键字声明该功能可能会出现问题
if(b<0){
throw new FushuException3("除数为负数"+b);<strong>//自定义异常jvm不认识,需要手动抛出</strong>
}<span style="white-space:pre"> </span> <strong>//手动通过throw关键字抛出一个自定义异常对象</strong>
<span style="white-space:pre"> </span>return a/b;
}
}
class FushuException3 extends Exception{
private String meg;
public FushuException3(String meg) {
super(meg);
}
}
//class FushuException extends Exception{
// private String meg;
// public FushuException(String meg) {
// this.meg=msg;
// }
// public String getMessage(){
// return meg;
// }
//}
4 finally 应用场景
package day09;
/*
*
* finally 应用场景
*
* 连接数据库
* 数据操作
* 关闭数据库
*
* try{
* 连接数据库
* 数据操作
* }
* catch (Exception e){
* 对数据库进行异常处理//处理本层问题
* throw new NoException();//返回相关信息
* }
* finally
* {
* 关闭数据库
* }
* finally 代码块,定义一定执行的代码
* 通常用于关闭资源
* 否则容易造成资源使用压力
*
* */
class Demo4{
int div(int a,int b) throws FushuException{
//通过throws关键字声明该功能可能会出现问题
if(b<0){
throw new FushuException("除数为负数"+b);//手动抛出异常
}
return a/b;
}
}
class ExceptionDemo4 {
public static void main(String args[]) {
Demo4 demo4=new Demo4();
try {
int x=demo4.div(4, 1);
} catch (FushuException e) {
System.out.println(e.toString());
}finally{
System.out.println("finally");
//finally中存放一定会执行的代码
}
System.out.println("over");
}
}
class NoException extends Exception{
}
class FushuException extends Exception{
private String meg;
public FushuException(String msg) {
this.meg=msg;
}
public String getMessage(){
return meg;
}
}
5 异常 格式
package day09;
/*
* try - catch -finally 的 格式
*1:try -catch
*2:try -catch -finally
*3:try -finally
*4:try -catch-catch
*
*catch 用于处理异常,如果没有catch代表异常
*没有被处理,
*如果该异常为检测时异常,必须声明
**/
/*
* class Demo6{
public void method(){
throw new Exception();
//编译不通过
}
}*/
/*
* class Demo6{
public void method(){
try {
throw new Exception();//编译通过
} catch (Exception e) {
}
}
}*/
/*
class Demo6{
public void method(){
try {
throw new Exception();
} catch (Exception e) {
try {
throw e;//编译通过
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}*/
class Demo6{
public void method() throws Exception{
try {
throw new Exception();
}finally{
//关资源 。必须要执行的代码
}
}
}
public class ExceptionDemo6 {
public static void main(String args[]) {
System.out.println("heo");
}
}
6 异常 在子父类中 的使用
package day09;
/*
* 异常在子父类覆盖中的体现
* 1:子类在覆盖父类时,如果父类发方法抛出异常
* 那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类
*
* Exception
* |--AException
* |--BException
* |--CException
* 2:如果父类方法抛出多个异常,那么子类方法
* 在覆盖方法时,子类只能抛出父类异常的子集
* 3:如果父类或者接口的方法中没有异常抛出,那么子类在方法
* 覆盖方法时,也不可以抛出异常,
* 如果子类方法发生了异常,就必须进行try 处理
* 绝对不能抛;
* */
class AException extends Exception{
}
class BException extends AException{
}
class CException extends Exception{
}
class Fu{
void show() throws AException{
}
}
class Zi extends Fu{
void show() throws BException{
//要么不抛,要么抛A或BException
//不能抛CExecption
}
}
class Test7 {
void fun(Fu fu) {
try {
fu.show();
} catch (AException e) {
}
}
}
public class ExceptionDemo7 {
public static void main(String[] args) {
Test7 test=new Test7();
test.fun(new Fu());
}
}
7 测试
package day09;
/*
* 有一个圆形和长方形
* 都可以获取面积,对于面积出现非法的数值,视为获取面积出现的问题
* 通过异常表示,*/
class NoValueException extends Exception{
public NoValueException(String msg) {
super(msg);
}
}
class NoValueException2 extends RuntimeException{
public NoValueException2(String msg) {
super(msg);
}
}
interface Shape{
void getArea();
}
class Circle implements Shape{
private int radius;
static final double PI=3.14;
Circle(int radius){
if (radius<0) {
throw new RuntimeException("非法值 Circle");
}
this.radius=radius;
}
@Override
public void getArea() {
System.out.println(radius*radius*PI);
}
}
class Res implements Shape{
private int len,wid;
Res( int len,int wid) throws NoValueException {
if (len <0||wid<0) {
throw new NoValueException("出现非法值 Res");
}
this.len=len;
this.wid=wid;
}
@Override
public void getArea() {
System.out.println(len*wid);
}
}
class Res2 implements Shape{
private int len,wid;
Res2( int len,int wid) {
if (len<0||wid<0) {
throw new NoValueException2("非法值 Res2");
}
this.len=len;
this.wid=wid;
}
@Override
public void getArea() {
System.out.println(len*wid);
}
}
public class ExceptionTest1{
public static void main(String args[]) {
Res res = null;
Res2 res2 = null;
/*
try {
res = new Res(-3, 4);
res.getArea();
}
catch (NoValueException e) {
// e.printStackTrace();
System.out.println(e.toString());
}
*/
//
// res2 = new Res2(-3, 4);
// res2.getArea();
// System.out.println("over");
Circle circle=new Circle(-8);
circle.getArea();
}
}
《黑马程序员 java 基础 毕向东 面向对象 异常》: 介绍了java中的异常机制,异常的使用场景,自定义异常 的使用以及注意事项。
package pack;
/*
* 包与包之间进行访问,被访问的包中的类以及类中的成员需要public修饰
* 不同包中的子类还可以直接访问父类中被protected权限修饰的成员
*
* 包与包之间可以使用的权限只有两种,public 和 protected
* ———————— |————————|———————————|—————————|——————————|
* | public | protected | default | private |
* ———————— |———————— |———————————|—————————|——————————|
* 同一个类中 | ok | ok | ok | ok
* 同一个包中 | ok | ok | ok |
* 子类(不同包)| ok | ok |
* 不同包中 | ok |
*
*
* 为了简化类名的书写,使用关键字 import
* import pack.haha.*;
* import 导入包中的类,而且只导入class文件
* 建立不要写通配符 *,用哪个类就导入哪个类
* 建立定义包名不要重复,可以使用URL的完成定义
* pack cn.itcast.demo
* pack cn.itcast.test
*
*
* jar 包
* 方便携带,使用
* */
class DemoA {
void show(){
System.out.println("show");
}
}