引言
新建一个Student类
public class Student {
public int age;
}
再新建一个Test类
public class Student {
new Student().age=100;
}
显然这个时候age为public级别的变量,则定义Student类的人无法对该变量的范围进行有效的约束,其他类在引用的时候可以随意赋值,并且age的值也会改变,于是处于安全性考虑,应该封装,通过公共方法操作私有属性。
public int getAge() {
return age;
}
public int setAge(int age) {
this.age=age;
}
因为学生的年龄有范围,所以要限制其他人不能输入超过限制的数据,因此代码变成了这样——
public void setAge(int age) {
if (age>1&&age<20) {
this.age = age;
}else {
System.out.println(“年龄范围超出”);
}
}
因此,其他人调用的age时候,如果赋值超出限制,控制台就会输出“年龄范围超出”
深入思考
控制台就会输出“年龄范围超出”,这样就够了吗?
显然,这个时候控制只有一句话“年龄范围超出”,但是一旦项目庞大起来,成百上千个类哪个环节出错了,单凭借这样一句话是几乎不可能迅速准确的找到出错未知,这个时候我们就需要改变思路,采用抛出异常的方法,即throw 异常对象
•throw用于抛出具体异常类的对象,一般用于方法体中。
•什么时候使用:当所写的代码因不满足某些条件致使程序无法运行时可以借助throw抛出一个异常对象提醒程序员。
如图,当b为0时不满足下面输出语的执行条件,所以使用throw关键字抛出运行时异常,用于提醒方法调用者
为什么那里不使用普通的System.out.println()进行提示?普通的输出仅仅是输出一句话,无法像抛出异常那样能准确定位到代码出错的位置,执行下面备注代码,进行比较即可知道
输出结果
•throw关键字一般用在方法体中,也可以用在代码块中,但如果代码块中抛出的异常对象是由检查时异常创建的,则必须使用try-catch进行处理;
如果替换成new RuntimeException(“操作失败:分母不能为0”),则可以省去try-catch语句块。
•throw将异常对象抛给谁
- 抛给自己
异常抛出后直接使用try-catch进行处理
2、抛给方法调用者
仅仅使用throw关键字将异常对象抛出,此处没做任何处理;如果抛出的异常类对象是由检查时异常类创建的,则还需要使用throws抛出抛出创建该异常对象的异常类或其父类,参见备注示例代码
方法调用者使用try-catch处理该异常(推荐)
方法调用者继续上抛该异常,由于方法抛出的是运行时异常类创建的对象,所以可以如下这样做;如果抛出由检查时异常类创建的对象,则这种处理方式必须使用throws关键字抛出创建该对象的异常类或其父类
•使用throw抛出异常对象如果没有try-catch捕获该异常对象,则该抛出异常对象语句执行后其所在方法结束执行。
由于age为1000时if条件语句执行,又因为没有对抛出的异常使用try-catch捕获,所以此行代码不执行。
因为调用div方法时会该方法抛出了异常对象,而调用方法的代码没有try-catch进行捕获处理,所以所以此行代码(红圈)不执行
由于调用方法时b为0,if条件语句执行,又因为没有对抛出的异常使用try-catch捕获,所以此行代码(蓝圈)不执行
•throws用于声明方法可能抛出的异常,其后为异常类,可以有多个,异常类之间用英文逗号间隔。
•什么时候使用throws关键字:
- 当方法体中的throw关键字抛出由检查时异常创建的对象时,如果该异常对象在抛出的同时已经通过try-catch进行了处理,则可以不使用throws,否则必须使用throws抛出创建该对象的异常类或其父类。
- 所调用的方法抛出了检查时异常时,如果该方法在调用的同时已经通过try-catch进行了处理,则可以不使用throws继续上抛该异常,否则必须使用throws才能上抛该异常,此时上抛的异常类可以是调用方法时方法抛出的异常类也可以是其父类。
•如果方法中的异常已经通过try-catch进行了捕获则无需再使用throws上抛该异常了,否则即使上抛也无效,只会做无用功。
此处异常已经通过try-catch语句进行了处理,所以show方法无需再使用throws抛出异常了,否则即使上抛也无效:执行代码会发现,即使这里异常被触发了,在main方法中catch依然没有执行,所以此时在通过throws抛出异常类纯属无用功。
•如果方法中的代码或者方法中所调用的代码没有使用throw抛出异常类对象,则无需使用throws否则该throws所抛出的异常类无效:即使用throws则其方法中的代码一定存在使用throw抛出异常对象的代码。
由于该方法中只是一个简单的输出语句,方法体和方法体中所调用的方法均没有使用throw抛出异常对象,所以此处没有必要使用throws抛出异常类,即便抛出了也是无用的——由于这里使用了throws抛出了异常类,main方法对该异常类进行了处理,可是我们会发现main方法中的catch语句块永远不可能执行。
throw与throws的区别
•throw与throws的区别:
抛出的东西不同:throw抛出的是具体的异常对象,而throws抛出的是抽象的异常类;
使用位置不同:throw一般用在方法体中,也可用在代码块中,但是如果抛出的是检查时异常类创建的对象,则必须使用try-catch自行处理;throws只能用在方法声明括号后面;
总结
throw用于抛出异常对象;
1、如果异常对象为运行时,则方法参数列表后面可以不是使用throws,也可以将异常抛给方法调用者;try catch
2、如果异常对象为检查时,则方法参数列表后面必须使用throws抛出创建该对象的类;如果没有throws 必须try-catch
throw与throws的区别:
抛出的东西不同:throw抛出的是具体的异常对象,而throws抛出的是抽象的异常类;
使用位置不同:throw一般用在方法体中,也可用在代码块中,但是如果抛出的是检查时异常类创建的对象,则必须使用try-catch自行处理;
throws只能用在方法声明括号后面;