throw关键字
当程序发生异常而无法处理的时候,会抛出对应的异常对象。
初次之外,在某些时刻我们可能会想要自行抛出异常,例如在异常处理结束后,再将异常
抛出,让下一层异常处理块来捕捉,若想要自行抛出异常,可以使用throw关键字,
并生成指定的异常对象抛出。
throw是一个动作,是抛出异常。
throw new ArithmeticExeption(),主动抛出异常。
throws关键字
throws用来在方法声明的同时,标明方法可能抛出的异常。定义方法可能会抛出的异常。
告诉该方法在运行的时候可能会出现这样的异常,在代码中一定要对相应的异常进行处理。
只有一类异常,抛出的时候方法可以不用声明,就是RuntimeException异常。
main()方法时处理异常的最后一个阵地。
package exception; /** * 使用当前类测试异常的抛出 * @author 小明 * */ public class Person { private int age; public int getAge() { return age; } public void setAge(int age) throws Exception{ if(age <0 || age > 100){ //throw new RuntimeException("年龄不合法"); /** * 当一个方法中使用throw抛出一个异常时 * 就要在当前方法上使用throws声明该异常的抛出以便通知调用 * 在调用当前方法时要处理异常。 * 只有RuntimeException及其子类在抛出时 * 编译器不要求必须写throws声明,其他异常则必须声明 * 否则编译不通过。 */ throw new Exception("年龄不合法"); //抛出异常的目的就是为了告诉外界,这里可能会抛出异常 //如果这里用try-catch //写throw的目的就是为了告诉外界这里可能会有问题 //处理别人抛出的异常时,才用try-catch或throws /** * 为什么在以前写流的时候一定要捕获异常, * 那是因为流的构造方法里就抛出了异常,在创建的时候,我们必须捕获这个 * 异常,处理异常。 */ } this.age = age; } }
package exception; /** * 测试异常的抛出 * @author 小明 * */ public class ThrowDemo { public static void main(String[] args) { Person person = new Person(); /** * 通常一个方法抛出异常有两种情况 * 1:方法当中遇到了满足语法要求,但是不满足 * 业务逻辑要求(下面的案例就是这种情况) * 2:方法中确实出现了异常,但是该异常不应当有该方法处理时, * 会抛出给调用者解决 */ /** * 碰到异常的时候,首先要知道是什么错 * 异常:1.指定抛出的异常 * 2.将异常抛出给相应的方法,该方法没有进行处理 * 找异常at语句从自己写的类开始看 * 该方法没有处理异常时,程序就被kill了。 */ try { person.setAge(1000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(person.getAge()); } }
使用throws语句抛出异常的方法在被重写的时候有一定的规则:
package exception; import java.awt.AWTException; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.SQLException; /** * 子类重写父类含有throws声明异常抛出的方法时对throws * 的重写规则 * @author 小明 * */ public class ThrowsDemo { public void dosome()throws IOException, AWTException { } //重写时可以不再抛出任何异常 } class Son extends ThrowsDemo{ /** * 子类抛出的异常可以是父类抛出异常的子类型 * */ //和父类抛出相同的异常 // public void dosome()throws IOException, AWTException // { // // } // 不抛出异常 // public void dosome() // { // // } //抛出父类中抛出异常类的子类 // public void dosome()throws FileNotFoundException // { // // } //不能抛出额外异常。 // public void dosome()throws SQLException // { // // } //不能抛出比父类更高的异常类 // public void dosome()throws Exception // { // // } }
java异常可以分为可检测异常,非检测异常:
在java中只有RuntimeException及其子类是非检测异常,其他都是检测异常。
可检测异常:可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理货声明规则,不捕获这个异常,编译器就通不过,不允许编译。
非检测异常:非检测异常不遵循处理或者声明规则。在产生此类异常时,不一定非要采取适当
操作,编译器不会检查是否已经解决了这样一个异常。
RuntimeException类属于非检测异常,因为普通JVM操作引起的运行时异常随时可能发生,
此类异常一般是特定操作引发。但这些操作在java应用程序中会频繁出现,因此它们不受编译器检查与处理或声明规则的限制。
比如说最常见的异常--空指针异常就是非检测异常,非检测异常时不会抛出的。
还有下标越界,数字格式异常。
异常里最常用的方法:就printStackTrace()。输出错误信息,有助于找到并解决错误。
自定义异常
目的:有时候java提供的异常不足以说明我们碰到的问题。
根据我们的需求抛出我们想要抛出的异常。主要我们是想根据抛出的异常类名知道程序到底抛出了什么样的异常。通过异常的名字马上就知道发生了什么问题,所以我们要自定义异常。
比如说年龄设定异常,java中没有这样的异常,所以我们要创建这样的异常类。
package exception; /** * 年龄不合法异常 * * 自定义异常,通常用来说明我们程序中某个业务逻辑错误 * 因为java提供的异常基本上没有实际项目中的业务错误 * 这是我们可以自行定义一个异常。 * @author 小明 * */ /** * 需要做几件事 * 最重要就是异常类名字--要求见名知意 * @author 小明 * */ public class IIlegalAgeException extends Exception{ /** * */ private static final long serialVersionUID = 1L; //为什么要有这条语句 /** * 因为Exception继承自Throwable,而Throwable实现了Serializable接口 * 实现了序列化接口就要有版本号 */ public IIlegalAgeException() { super(); // TODO Auto-generated constructor stub } public IIlegalAgeException(String arg0, Throwable arg1, boolean arg2, boolean arg3) { super(arg0, arg1, arg2, arg3); // TODO Auto-generated constructor stub } public IIlegalAgeException(String arg0, Throwable arg1) { super(arg0, arg1); // TODO Auto-generated constructor stub } public IIlegalAgeException(String arg0) { super(arg0); // TODO Auto-generated constructor stub } public IIlegalAgeException(Throwable arg0) { super(arg0); // TODO Auto-generated constructor stub } }
Person.java
package exception; /** * 使用当前类测试异常的抛出 * @author 小明 * */ public class Person { private int age; public int getAge() { return age; } public void setAge(int age) throws IIlegalAgeException{ if(age <0 || age > 100){ //throw new RuntimeException("年龄不合法"); /** * 当一个方法中使用throw抛出一个异常时 * 就要在当前方法上使用throws声明该异常的抛出以便通知调用 * 在调用当前方法时要处理异常。 * 只有RuntimeException及其子类在抛出时 * 编译器不要求必须写throws声明,其他异常则必须声明 * 否则编译不通过。 */ throw new IIlegalAgeException("年龄不合法"); //抛出异常的目的就是为了告诉外界,这里可能会抛出异常 //如果这里用try-catch //写throw的目的就是为了告诉外界这里可能会有问题 //处理别人抛出的异常时,才用try-catch或throws /** * 为什么在以前写流的时候一定要捕获异常, * 那是因为流的构造方法里就抛出了异常,在创建的时候,我们必须捕获这个 * 异常,处理异常。 */ } this.age = age; } }
ThrowDemo.java
package exception; /** * 测试异常的抛出 * @author 小明 * */ public class ThrowDemo { public static void main(String[] args) { Person person = new Person(); /** * 通常一个方法抛出异常有两种情况 * 1:方法当中遇到了满足语法要求,但是不满足 * 业务逻辑要求(下面的案例就是这种情况) * 2:方法中确实出现了异常,但是该异常不应当有该方法处理时, * 会抛出给调用者解决 */ /** * 碰到异常的时候,首先要知道是什么错 * 异常:1.指定抛出的异常 * 2.将异常抛出给相应的方法,该方法没有进行处理 * 找异常at语句从自己写的类开始看 * 该方法没有处理异常时,程序就被kill了。 */ try { person.setAge(1000); } catch (IIlegalAgeException e) { //e.printStackTrace(); System.out.println("出错了"); } System.out.println(person.getAge()); } }