9异常



1异常

  • 异常都继承于Exception
  • 用分为运行时异常(RuntimeException)和非运行时异常
  • 运行时异常由JVM自动抛出,非运行时异常手动抛出(throw)
    finally中的代码块一定会执行


1.1异常的捕获和处理

用:try{

           会出现异常的代码

            }catch(异常类){处理代码}

例:

	public static void main(String[] args) {
		di();
	}
	
	//示例方法
	public static void di(){
		int a = 3/0;
	}
因为0不能做除数,所以调用di()方法是执行到这句会报错:

java.lang.ArithmeticException: / by zero
    at te.st.yichang.Test1.di(Test1.java:16)
    at te.st.yichang.Test1.main(Test1.java:7)

所以可以用try,catch语句块来捕获和处理。例:

	//用try,catch来捕获处理
		try {
			di();
		} catch (ArithmeticException e) {
			System.out.println("这是我自己处理的异常");
		}
输出的结果是:这是我自己处理的异常

1.11异常类有两个方法好用的方法:

e.getMessage():获取导致异常的消息

e.printStackTrace():打印导致异常的路径和消息

例:

		//用try,catch来捕获处理
		try {
			di();
		} catch (ArithmeticException e) {
			String str = e.getMessage();
			System.out.println(str);
			
			e.printStackTrace();
		}
输出:

  / by zero
java.lang.ArithmeticException: / by zero
    at te.st.yichang.Test1.di(Test1.java:18)
    at te.st.yichang.Test1.main(Test1.java:7)


1.2运行时异常

运行时异常有JVM自动抛出,它会一直往上抛,直到程序结束,然后直接终止程序

例:写一个类继承RuntimeException,

/*
 * 写一个类继承于RuntiamException
 * */
class MyRuntimeException extends RuntimeException{
	//
	public void di(){
		int a = 3/0;
	}
	
}

main入口:
	public static void main(String[] args) {
		//实例化
		MyRuntimeException me = new MyException();
		//
		me.di();
		
		System.out.println("我是语句块外面的");
	}
输出结果是:直接报错终止程序

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at te.st.yichang.MyException.di(Test4.java:21)
    at te.st.yichang.Test4.main(Test4.java:8)

System.out.println("我是语句块外面的");
这句话就没有被执行

这是应为运行时异常是直接向上抛出的,执行到int a = 3/0时发现异常,JVM直接抛到main方法中,main方法中又没有捕获和处理这个异常,又向上面抛,由于mian上面已经无处可抛,就直接终止程序,main中di()后面的语句就不会执行;

用try,catch捕获处理就不会了:

修改main:用try,catch捕获

	public static void main(String[] args) {
		//实例化
		MyException me = new MyException();
		//
		try {
			me.di();
		} catch (ArithmeticException e) {
			System.out.println("我已经捕获处理了该异常");
		}
		
		System.out.println("我是语句块外面的");
	}
输出结果:

我已经捕获处理了该异常
我是语句块外面的

1.3,finally语句块

finally语句块内的语句一定会执行

例:

在try,catch的di()语句后面添加一句

	try {
			me.di();
			System.out.println("我是语句块内的");//添加一句
		} catch (ArithmeticException e) {
			System.out.println("我已经捕获处理了该异常");
		}
输出的还是:

我已经捕获处理了该异常

因为在try,catch中,前面的语句捕获到异常时,该语句后面的语句就不在去执行了,而是直接跳出语句块

所以需要添加finally

例:将其移到finally中

		//
		try {
			me.di();
		} catch (ArithmeticException e) {
			System.out.println("我已经捕获处理了该异常");
		}finally{
			System.out.println("我是语句块内的");
		}
输出结果:

我已经捕获处理了该异常
我是语句块内的


1.4非运行时异常

还有一种异常叫非运行时异常,这就需要程序员手动抛出,用throw关键字
有两种方式:

第一种:直接try,catch捕获处理
第二种:往上抛出,声明该方法为会产生异常,用throws关键(比throw多个s)

例:1写一个类,继承Exception

/*
 * 我自己写的异常,继承Exception
 * */
class MyException extends Exception{

	public MyException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public MyException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public MyException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public MyException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
	
}
2,Buy类,这里面的方法会产生异常:
class Buy{
	//身高
	int high;
	
	//买衣服的方法
	//size判断衣服是否合身,不合身就报异常
	public void clothes(int size) throws MyException{//这里我将异常声明在方法中抛出
		if(size==high){
			System.out.println("这件衣服很合身");
		}else if(size>high){
			//大了就好比一个异常
			//用throw抛出,throw new一个异常类
			//当用了throw时,就要处理这个异常,是要try,cath还是抛出,如果抛出就要在方法中用throws声明要抛出的异常类
			throw new MyException("衣服大了!");
		}else{
			throw new MyException("衣服小了");
		}
		
	}
}
main:
	public static void main(String[] args){
		Buy buy = new Buy();
		buy.high = 170;
		
		//调用的这个方法会产生异常,因为我在这个法中声明了会抛出MyException异常
		//两种处理方式
		//第一种,直接捕获处理
		try {
			buy.clothes(190);
		} catch (MyException e) {
			System.out.println(e.getMessage());
		}
	}

这里会输出:衣服大了

第二种就是再次向上抛出:

	public static void main(String[] args) throws MyException{//这种就需要在这个会出异常的方法中声明要抛出的异常
		Buy buy = new Buy();
		buy.high = 170;
		
		//调用的这个方法会产生异常,因为我在这个法中声明了会抛出MyException异常
		//两种处理方式
		//第二种,不处理往上抛出
		buy.clothes(190);
	}
输出结果:Exception in thread "main" te.st.yichang.MyException: 衣服大了!
    at te.st.yichang.Buy.clothes(Test4.java:31)
    at te.st.yichang.Test4.main(Test4.java:11)

对比两种,运行时异常就不用我们手动抛出,非运行时异常就要我们手动抛出,直到我们处理了这个异常或抛到最顶层(一般都是不会在main方法中再次抛出异常,这里只是示例)


1.5异常的多态

异常也是类,都是继承Exception所以异常也会有多态

要在try,catch中使用中注意

例:1,在写了一个异常类MyException2继承Exception,这里就不贴了(方法同上)

2,修改下Buy类。将衣服小了抛出MyException2,并该方法声明抛出throws Exception

	public void clothes(int size) throws Exception{//这里改为抛出Exception
		if(size==high){
			System.out.println("这件衣服很合身");
		}else if(size>high){
			throw new MyException("衣服大了!");
		}else{
			//这里改为抛出MYException2
			throw new MyException2("衣服小了");
		}
		
	}
3main:中就要捕获两个异常, 最后还要捕获父类的异常
		//捕获处理异常
		try {
			buy.clothes(190);
			//买件小衣服
			buy.clothes(120);
			
		} catch (MyException e) {	//捕获MyException
			System.out.println(e.getMessage());
		}catch(MyException2 e){	//捕获MyException2
			System.out.println(e.getMessage());
		}catch(Exception e){	//记住,最后还要捕获父类异常
			System.out.println(e.getMessage());
		}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值