Java中的异常

异常

  • 异常 :异常就是在程序运行的过程中 所发生的不正常的事件,它会**中断指令的正常执行 ** 。

  • 异常的原因 :用户输入错误、设备错误、代码错误、磁盘空间不足

  • 异常类之间存在继承关系

    • 计算机图片
    • 左侧是右侧的基类
    • ERROR :描述了Java运行系统中的内部错误以及资源耗尽错误
    • exception :程序中需要关注的
      • RuntimeException重点学习 ):在Java虚拟机 正常运行期间抛出的异常,由程序的错误导致
      • 其他异常 :如IO异常,SQL异常:一般是外部错误,Java编译器要求在程序中必须处理这类异常
  • 异常的分类

    • 未检查异常 :ERROR和RuntimeException
    • 受检异常: 其他异常。
  • 一旦发生异常,程序将会停止在出错的那一行,将不会在向下继续执行

  • RuntimeException 中常见的几种异常:

    • 算术异常(ArithmeticException

      • package net.onest.demo2;
        
        public class ExceptionTest {
        	public static void fun(int a,int b) {
        		System.out.println(a/b);
        	}
        	public static void main(String[] args) {
        		System.out.println("---程序开始要运行啦---");
        		fun(10,5);
        		System.out.println("---程序就此结束---");
        	}
        
        }
        //结果为:
        ---程序开始要运行啦---
        2
        ---程序就此结束---
        //这个时候程序没有发生任何错误,输出了正确的结果2
        
      • 但是当被除数是0的时候结果就会发生算术异常

        package net.onest.demo2;
        
        public class ExceptionTest {
        	public static void fun(int a,int b) {
        		System.out.println(a/b);
        	}
        	public static void main(String[] args) {
        		System.out.println("---程序开始要运行啦---");
        		fun(10,0);
        		System.out.println("---程序就此结束---");
        	}
        
        }
        //结果为:
        ---程序开始要运行啦---
        Exception in thread "main" java.lang.ArithmeticException: / by zero
        	at net.onest.demo2.ExceptionTest.fun(ExceptionTest.java:5)
        	at net.onest.demo2.ExceptionTest.main(ExceptionTest.java:9)
        即发生了算术异常,被除数我出了个0
        //说明程序停止在出错的那一行没有继续执行
        
    • 类型转换异常(ClassCastException)

      • package net.onest.demo2;
        
        public class ExceptionTest {
        	
        	public static void main(String[] args) {
        		System.out.println("---程序开始要运行啦---");
        		Object obj = new Integer(10);//向上转型
        		Double double1 = (Double)obj;
        		System.out.println(double1);
        		System.out.println("---程序就此结束---");
        	}
        
        }
        //结果为:
        ---程序开始要运行啦---
        Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
        	at net.onest.demo2.ExceptionTest.main(ExceptionTest.java:8)
        //即发生了类型转换异常,不能将Integer类型转换成Double类型
        
      • 解决办法 (用if语句进行判断)

        package net.onest.demo2;
        
        public class ExceptionTest {
        	
        	public static void main(String[] args) {
        		System.out.println("---程序开始要运行啦---");
        		Object obj = new Integer(10);//向上转型
        		if(obj instanceof Double) {
        			Double double1 = (Double)obj;
        			System.out.println(double1);
        		}
        		System.out.println("---程序就此结束---");
        	}
        
        }
        //结果为:---程序开始要运行啦---
        //---程序就此结束---
        
        
    • 数组下标月结异常(ArrayIndexOutOfBoundsException)

      • package net.onest.demo2;
        
        public class ExceptionTest {
        	
        	public static void main(String[] args) {
        		System.out.println("---程序开始要运行啦---");
        		int[] nums = {10,20,30,40};
        		System.out.println(nums[4]);
        		System.out.println("---程序就此结束---");
        	}
        
        }
        //结果为:
        ---程序开始要运行啦---
        Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
        	at net.onest.demo2.ExceptionTest.main(ExceptionTest.java:8)
        
        
    • 字符串下标越界异常(StringIndexOutOfBoundsException

      • package net.onest.demo2;
        
        public class ExceptionTest {
        	
        	public static void main(String[] args) {
        		System.out.println("---程序开始要运行啦---");
        		String str = "asd";
        		System.out.println(str.charAt(3));
        		System.out.println("---程序就此结束---");
        	}
        
        }
        //结果为:Exception in thread "main" ---程序开始要运行啦---
        java.lang.StringIndexOutOfBoundsException: String index out of range: 3
        	at java.lang.String.charAt(Unknown Source)
        	at net.onest.demo2.ExceptionTest.main(ExceptionTest.java:8)
        
        
  • 空引用异常 (分析点号前,他可能是空对象)

    • package net.onest.demo5;
      
      public class Expection {
      	private static String getCellValue(int i) {
      		if(i<4) {
      			return "单元格内容";
      		}else {
      			return null;
      		}
      	}
      	public static void main(String[] arga) {
      		//空引用异常 
      		String str = getCellValue(4);//传入4的时候返回的是null,引发了空引用异常
      		System.out.println(str.charAt(0));
      	}
      }
      
      
    • 解决

      • //引用类型与空对象判等可以直接使用==或!=
        package net.onest.demo5;
        
        public class Expection {
        	private static String getCellValue(int i) {
        		if(i<4) {
        			return "单元格内容";
        		}else {
        			return null;
        		}
        	}
        	public static void main(String[] arga) {
        		
        		//空引用异常 
        		String str = getCellValue(4);
        		if(str != null) {
        			System.out.println(str.charAt(0));
        		}
        		
        	}
        }
        
        
    • 类未找到异常

      • package net.onest.demo;
        
        public class ExceptionTest {
        
        	public static void main(String[] args) {
        		System.out.println("------程序开始");
        		//6.检查异常(受检异常)类型未找到
        		//参数是类的全限定名,作用加载类到内存
        		try {
        			//可能出现异常的代码
        			Class.forName("net.onest.demo.Student");
        			System.out.println("没有异常");
        		}catch(ClassNotFoundException e) {
        			//产生异常时执行(处理异常)
        			System.out.println("有异常了");
        			e.printStackTrace();//打印异常的堆栈信息
        		}
        		System.out.println("------程序结束");
        	}
        	
        }
        //Class.forName(),装载一个类并对其进行实例化的操作
        
    • 出现空引用异常一定是某个引用类型指向了空对象

    • 出错的一定是提示里面的最上面一行 :查看控制台提示哪里出错的时候,一定是提示的最上面一行出错了。

    • 对所有引用类型的引用都要看是否是空引用(是否分配内存空间)

    • **(捕获异常)try catch ** 不会中断,会执行catch语句

      • package net.onest.demo;
        
        public class ExceptionTest {
        
        	public static void main(String[] args) {
        		System.out.println("------程序开始");
                
                
        		String str = getCellValue(4);//str = null
                
                
        		try {
        			System.out.println(str.charAt(0));//将是空引用异常
        		}catch(ArithmeticException e) {//算术异常,与空引用异常不匹配,所以不会执行catch语句
        			System.out.println("算术异常");
        		}
        		
        		//异常导致程序的中断
        		System.out.println("------程序结束");
        	}
        	
        	private static String getCellValue(int i) {
        		if(i < 4) {
        			return "单元格的内容";
        		}else {
        			return null;
        		}
        	}
        	
        }
        
        //输出结果为:
        //Exception in thread "main" ------程序开始
        //java.lang.NullPointerException
        //	at net.onest.demo2.StaticTest.main(StaticTest.java:20)
        //由上面的程序我们发现,try语句块发生异常的时候,回去看异常类型与catch类型是否匹配,匹配执行catch语句,catch语句后的代码会正常执行,但是如果catch语句与异常类型不匹配的话,程序就此中断,下面的语句也不会再继续执行了
        
    • try中有语句中断,那么该语句下面的所有属于try的都不会再执行 ,但是会执行catch语句和其他语句块

      • package net.onest.demo;
        
        public class ExceptionTest {
        
        	public static void main(String[] args) {
        		System.out.println("------程序开始");
                
                
        		String str = getCellValue(4);//str = null
                
                
        		try {
                     System.out.println("这条语句会执行");
        			System.out.println(str.charAt(0));//将是空引用异常
        		}catch(ArithmeticException e) {//算术异常,与空引用异常不匹配,所以不会执行catch语句
        			System.out.println("算术异常");//不会输出该语句
        		}
        		
        		//异常导致程序的中断,不会输出该语句
        		System.out.println("------程序结束");
        	}
        	
        	private static String getCellValue(int i) {
        		if(i < 4) {
        			return "单元格的内容";
        		}else {
        			return null;
        		}
        	}
        	
        }
        
        //------程序开始
        //这条语句会执行
        //Exception in thread "main" java.lang.NullPointerException
        //	at net.onest.demo5.Colors.main(Colors.java:55)
        
        
    • 一段代码可能会生成多个异常。只会有一个try但可以有多个catch

      • public static void main(String[] args) {
        		try {
        			fun(10,0);
        		}catch(ArithmeticException e){
        			System.out.println("发生了算术异常");
        			e.printStackTrace();
        		}catch(IndexOutOfBoundsException e) {
        			System.out.println("下标越界异常");
        			e.printStackTrace();//打印堆栈信息,每次代码都要写上
        			
        		}catch(NullPointerException e){
        			System.out.println("空指针异常");
        			e.printStackTrace();
        		}
        	}
        	public static void fun(int a,int b) {
        		System.out.println(a/b);
        	}
        

  • 当引发异常时,会按顺序**(从上到下 )来查看每个 catch 语句** ,并执行第一个类型与异常类型匹配 的语句。

  • 执行其中的一条 catch 语句之后,其他的 catch 语句将被忽略。

  • 使用多重 catch 语句时,异常子类一定要位于异常父类之前 。否则会编译出错 ,不会再去找到子类了(先写基类可以匹配到–存在向上转型

  • 一个catch语句中存放多个异常类型,但只有一个标识符e,但是多个类型之间不能有继承关系(不建议使用这种方法)

    • try {
      i = a / b;
            System.out.println("try block");
      } catch (IndexOutOfBoundsException | ArithmeticException e1) {
            System.out.println("发生异常,请处理该异常!");
      }
      
      
    • 很少使用try catch在未受检异常(使用else if可以实现),在**受检异常内经常使用try catch中 **
  • finally:回收资源

  • **try+catch 或者try+finally 或者 try+catch +finally ** 他们都是紧随其后的,中间不能有其他代码

    • public static void main(String[] args) {
      		try {
      			fun(10,0);
      		}catch(ArithmeticException e){
      			System.out.println("发生了算术异常");
      			e.printStackTrace();
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("下标越界异常");
      			e.printStackTrace();
      			
      		}catch(NullPointerException e){
      			System.out.println("空指针异常");
      			e.printStackTrace();
      		}finally {
      			System.out.println("回收资源");
      		}
      	}
      	public static void fun(int a,int b) {
      		System.out.println(a/b);
      	}
      
      //无论是否发生异常,catch语句是否执行,总会输出“回收资源”
      
    • public static void main(String[] args) {
      		try {
      			fun(10,0);
      		}finally {
      			System.out.println("回收资源");
      		}
      	}
      	public static void fun(int a,int b) {
      		System.out.println(a/b);
      	}
      
  • finally总是会执行 ,即无论是否发生异常,finally总是会执行

  • 强制退出程序System.exit(0) 一旦运行到这句话那么该句话下面的所有代码均不会被执行包括finally语句 ,强制退出程序

    • public static void main(String[] args) {
      		try {
      			System.out.println("程序会执行这句话");
      			System.exit(0);
      			fun(10,0);
      		}catch(ArithmeticException e){
      			System.out.println("发生了算术异常");
      			e.printStackTrace();
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("下标越界异常");
      			e.printStackTrace();
      			
      		}catch(NullPointerException e){
      			System.out.println("空指针异常");
      			e.printStackTrace();
      		}finally {
      			System.out.println("回收资源");
      		}
      	}
      	public static void fun(int a,int b) {
      		System.out.println(a/b);
      	}
      
      //结果为:“成簇会执行这句话”
      //该程序将不会在产生异常,因为还没有调用fun()函数之前该程序就被强制退出了,所以不会再出现异常
      

抛出异常

  • throws关键字:形参列表小括*

  • throws作用 :声明该方法可能会抛出的异常类型

  • throw: 使用throw抛出异常 。先创建异常类型的对象,再throw+对象名,一旦执行throw一定是出异常了

  • 加上判断看是否抛出异常(我做的),如果我不写,那么当b=0时,虚拟机会抛出这个异常

  • 抛出异常只是暂时解决了写程序的人的困难,解决困难还是需要用户使用try catch语句捕获异常

  • 抛出的异常类型是Java虚拟机没有的,Java虚拟机有的话无论写不写,一旦异常了,总会有输出

  • 自定义异常 (受检异常(exception)、为受检异常(error、runtimeexception))

    • 继承某个异常类

    • 重写三个方法

      • package net.onest.demo5;
        
        public class IllegalAgeExpection extends Exception{
        
        	@Override
        	public String getMessage() {
        		return "年龄不符合要求";
        	}
        	
        	@Override
        	public void printStackTrace() {
        		// TODO Auto-generated method stub
        		System.out.println(getMessage());
        		super.printStackTrace();
        	}
        	
        	@Override
        	public String toString() {
        		// TODO Auto-generated method stub
        		return "年龄不合法";
        	}
        }
        
        
      • 抛出异常

        package net.onest.demo2;
        
        public class Ok {
        	private int age;
        
        	public int getAge() {
        		return age;
        	}
        
        	public void setAge(int age) throws IllegalAgeException{
        		if(age < 16 || age > 70) {
        			throw new IllegalAgeException();
        		}
        		this.age = age;
        	}
        	
        
        }
        
        
    • 捕获自定义异常类型

      • try {
        			Student stu = new Student();//先定义对象
        			stu.setAge(10);
        		}catch(IllegalAgeException e) {
        			e.printStackTrace();
        		}
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值