在讲throw与throws之前,先讲一下封装
首先看下面代码
# Student类
public class Student {
public int age;
}
#Test类
public class Test {
public static void main(String[] args) {
new Student().age = 1000;
}
}
我们知道人的年龄是有限的,不可能是1000,但上面代码无法控制年龄的范围,所以不合理。
如果Student类中的变量为public级别的变量,则定义Student类的人无法对该变量的范围进行有效的约束 ,这时需要用到公共方法操作私有属性,即“封装”,看下面代码
# Student类
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0 && age<70) {
this.age = age;
}else {
System.out.println("年龄无效");
}
}
}
#Test类
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setAge(100);
System.out.println(student.getAge());
}
}
结果:这时就约束了范围,这个过程就是封装
但是:这种提示错误的方式对于调用该方法的程序员没有什么过多的直接的帮助,因为在很大的一个项目里,很难通过这种方式找到错误所在,那么如何解决这个问题呢?
解决方案:throw 异常对象
看以下代码
#Student类
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0 && age<70) {
this.age = age;
}else {
throw new NullPointerException("年龄无效");
}
}
}
#Test类
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setAge(100);
System.out.println(student.getAge());
}
}
用throw异常对象的话,就会显示出错原因及所错代码位置,如图
那么问题又来了,年龄出错并不是空指针异常,Java API提供的已有异常类无法准确表述当前发生的异常问题,那么如何更准确的表示异常类型呢?这时就需要创建自定义的异常了。那么如何创建呢?如下:
如何创建异常:
创建继承Exception 或其子类的自定义类;自定义异常类调用父类构造函数(通常是含有一个String类型参数的构造函数);
步骤一:在当前项目的src新建一个exception的包,在包中新建一个AgeException的类
步骤二:AgeException继承RuntimeException类,右击——sources——Generate Constructors from Superclass(倒数第二个)
会出现很多RuntimeException,可以都选,也可以只选一个,由于(String)最常用,现在选这一个
这样就创建完成了,如
创建完后,就可以调用了,(注意:不要忘记引包哦,因为在不同包中。引包:ctrl+shift+O键),如
#Student类
import exception.AgeException;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0 && age<70) {
this.age = age;
}else {
throw new AgeException("年龄无效");
}
}
}
#Test类
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setAge(100);
System.out.println(student.getAge());
}
}
结果:
throw用法
throw用于抛出异常对象;
* 1、如果异常对象为运行时,则方法参数列表后面可以不使用throws,也可以将异常抛给方法调用者;try-catch
AgeException继承的是RuntimeException
throw new AgeException("年龄无效");是将异常抛给方法调用者,如果Test类是下面这样
public class Test {
public static void main(String[] args) {
Student student = new Student();
try {
student.setAge(100);
} catch (Exception e) {
System.out.println("执行了");
e.printStackTrace();
}
System.out.println(student.getAge());
}
}
可以看到输出“执行了”,这证明Student将异常抛给了方法调用者
如果将异常抛给自己,那么就不会执行Test里的try-catch了
#Student类
import exception.AgeException;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>0 && age<70) {
this.age = age;
}else {
try {
throw new AgeException("年龄无效");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
#Test类
public class Test {
public static void main(String[] args) {
Student student = new Student();
try {
student.setAge(100);
} catch (Exception e) {
System.out.println("执行了");
e.printStackTrace();
}
System.out.println(student.getAge());
}
}
结果:没有输出“执行了”
* 2、如果异常对象为检查时,则方法参数列表后面必须使用throws抛出创建该对象的类;如果没有throws 必须try-catch
AgeException继承的是Exception
如果没有throws也没有try-catch,会出错
两种方法:
①使用throws抛出创建该对象的类,Test可以有try-catch,也可以是throws
②try-catch抛给自己,Test 类就不用throws或try-catch了
throw与throws的区别:
抛出的东西不同:throw抛出的是具体的异常对象,而throws抛出的是抽象的异常类;
使用位置不同:
throws只能用在方法声明括号后面;
throw一般用在方法体中,也可用在代码块中,但是如果抛出的是检查时异常类创建的对象,则必须使用try-catch自行处理