异常指代码编译运行时出现的问题
总称Exception,祖宗类Throwable
它的子类很多,大部分都是编译时错误,但RuntimeException子类确实运行时错误。
l RuntimeException和他的所有子类异常,都属于运行时期异常。Exception,ArrayIndexOutOfBoundsException等都属于运行时期异常.
l 运行时期异常的特点:
n 方法中抛出运行时期异常,方法定义中无需throws声明,调用者也无需处理此异常
n 运行时期异常一旦发生,需要程序人员修改源代码.
总结:
Throwable: 它是所有错误与异常的超类(祖宗类) |- Error 错误 |- Exception 编译期异常,进行编译JAVA程序时出现的问题 |- RuntimeException 运行期异常, JAVA程序运行过程中出现的问题
异常和错误不同点在于,错误会直接报错,就像游戏突然未响应,这就是报错。
而拿两个常见的异常来看虽然报错,但是我们可以修改代码。
package com.oracle.demo03; //Error:癌症只能修改代码 //Exception:异常 //RuntimeException-》癌症,没法处理,只能改代码 //Exception->感冒,可以处理 public class Demo01 { public static void main(String[] args) { int [] arr=new int[1000000000000000]; //OutOfMemoryError创建数组时,空间过大 } }
package com.oracle.demo03; public class Demo02 { public static void main(String[] args) { int [] arr={4,5}; int num=get(arr);//数组索引越界异常ArrayIndexOfBoundsException System.out.println(num); } public static int get(int [] arr){ int i=arr[2]; return i; } }
当我们看到这些控制台打印报错时,多亏了程序的帮忙,但是问题来了,我们如何对待这些异常呢?
有两种方式,throws和trycatchfindly
①throw抛出异常
声明异常throws
常用方法
package com.oracle.demo04; public class Demo07 { public static void main(String[] args) { //将异常给main int [] arr=null; //可能会产生异常代码 int num=getArr(arr); System.out.println(num); } //修饰符 返回值类型 方法名(参数)throw是 异常类名1 异常类名2 public static int getArr(int [] arr) { if(arr==null){ throw new NullPointerException("你传的数组是null"); //格式:throw new 异常类名() //将异常传给调用者,抛出异常 } if(arr.length==0){ throw new ArrayIndexOutOfBoundsException("你传的数组没有值"); } int i=arr[arr.length-1];//传最后一位,空值不行 return i; } }
也就是说,当我们的throw抛出异常给调用者,throws声明异常在方法里面,调用者发现我调用了这个异常方法,找找到了你这个判断,arr是空集合呀,然后控制台就提示出来了数组是null。
②trycatchfindly
图解:
package com.oracle.demo04; public class Demo5 { public static void main(String[] args) { //将异常给main //int [] arr=null; int [] arr={};//有数组但是没元素 //可能会产生异常代码,一般是传数和输出 try{ int num=getArr(arr); System.out.println(num); } catch(NullPointerException ex){//抛啥补啥,你的不合法 ex.printStackTrace(); }catch(ArrayIndexOutOfBoundsException ex){ ex.printStackTrace(); } catch(Exception ex){//运行产生异常,直接捕获处理,父类类型写最后面 System.out.println("出错啦"); ex.printStackTrace(); } finally{ System.out.println("不论发生异常与否,一定会执行的代码"); } System.out.println("HelloWord"); } //修饰符 返回值类型 方法名(参数)throw是 异常类名1 异常类名2 public static int getArr(int [] arr) throws NullPointerException, ArrayIndexOutOfBoundsException { if(arr==null){ throw new NullPointerException("你传的数组是null"); //格式:throw new 异常类名() //将异常传给调用者 } if(arr.length==0){//数组越界 throw new ArrayIndexOutOfBoundsException ("你穿的数组中没有值"); } int i=arr[arr.length-1];//传最后一位,空值不行 return i; } }
try的原则就是将可以导致报错的代码放在一起,catch就是报错之后去寻找到底是哪个错误,finadlly就是错误也会执行的代码。
因为java所有都是具有面向对象思想的,所以异常也是会继承的,这里循序的原则是,父类有子类可以重写,父类没有,子类不能重写。
比较特殊的情况是如果接口没有声明异常,但是子类有异常,只能用try catch捕获,所以这个比较万能。
异类也是有方法的
如我们前面的catch中捕获的catch(xxx e){
e.xxx();里面可以写toString 和printStrackTrace 和getMessage
}
自定义异常
所有我们的自定义类都要有是哪个原则,①自定义类②自定义异常③测试类
package com.oracle.demo05; public class Person extends RuntimeException { private String name; private int age; public Person(int age ,String name) { super(); if(age>200||age<0){ throw new ChaoChuException("超出"+age); } } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
自定义类里面我们写判断条件,并且抛出异常。
package com.oracle.demo05; public class ChaoChuException extends RuntimeException{ public ChaoChuException (String mess){ super(mess); } }
自定义异常里面继承运行期错误,继承运行期错误,并且写一个构造函数,传一个提示参数字符串类,但是目前的构造的方法没有可以在控制台上搞提示的怎么办,这时候我们就可以采用super(实参)
package com.oracle.demo05; public class Demo05 { public static void main(String[] args) { //Person p=new Person(-1,"lala"); get(); } public static void get(){ Person p=new Person(1000,"lala"); } }