异常
-
异常 :异常就是在程序运行的过程中 所发生的不正常的事件,它会**中断指令的正常执行 ** 。
-
异常的原因 :用户输入错误、设备错误、代码错误、磁盘空间不足
-
异常类之间存在继承关系
- 左侧是右侧的基类
- 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(); }
-
-