目录
一.封装
详情见博客:java封装
我们先在vo包中创建一个vo类,它的机理是当无效赋值时输出“年龄无效”提示调用者:
package com.jd.vo;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age){
if (age>1 && age<30) {
this.age = age;
}else {
System.out.println("年龄无效");
}
}
}
这时我们在另一个类中给Student类中age赋值时,如果赋一个100,运行结果如下:
package com.jd.vo;
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setAge(100);
System.out.println(student.getAge());
}
}
但还是存在着一个问题,当项目的代码量非常大的时候,此处打印一个“年龄无效”,程序员要想找到哪里出问题就必须依次检查,会浪费大量时间,所以这个vo类可以这么解决:
二.用throw
将Student类中的代码修改成NullPointerException的运行异常:
package com.jd.vo;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age){
if (age>1 && age<30) {
this.age = age;
}else {
throw new NullPointerException("年龄无效");
}
}
}
这时用Test类赋值100,就会提示错误出在哪里了,这样的异常提示会大大提高了排错的效率:
但是在上段代码的修改中,使用的是NullPointerException的运行异常,而实际上出现的异常原因是超出了赋值范围,可是JDK中并没有这么一个类,这时就需要我们自己定义一个异常。
三.自定义异常
在另一个包中创建一个AgeException类,由于该异常为运行时异常,所以继承的是RuntimeException类,并在其中假如构造方法:
package com.jd.exception;
public class AgeException extends RuntimeException{
private static final long serialVersionUID = -1829894057306300522L;
public AgeException(String message) {
super(message);
}
}
将鼠标放到类名上,点击如下的链接Add generated serial version ID导入编号:
一个异常类就自定义完毕,最后得到的代码就是这样:
package com.jd.exception;
public class AgeException extends RuntimeException{
private static final long serialVersionUID = -1829894057306300522L;
public AgeException(String message) {
super(message);
}
}
这时再执行一次Test类得到的运行结果就是自定义的AgeException异常的提示了:
四.throws的用法
刚才用的throw的实质是将该异常抛给调用该方法的调用者,也就是Test类,让调用者去处理该异常。
而处理异常的方法还有一种就是在Student类中自己处理掉,操作就是对该throw语句用try-catch语句:
package com.jd.vo;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age){
if (age>1 && age<30) {
this.age = age;
}else {
try {
throw new AgeException("年龄无效");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
上述的所有操作都是在AgeException异常是运行时异常的前提下,那么如果将AgeException定义为检查时异常,即让AgeException类继承Exception类,这时throw语句必须要么用try-catch语句在Student中将异常自己处理掉,要么将异常抛给方法的调用者,即Test类。但是这时下段代码便会报错:
package com.jd.vo;
import com.jd.exception.AgeException;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age){
if (age>1 && age<30) {
this.age = age;
}else {
throw new AgeException("年龄无效");
}
}
}
这是因为将异常抛给调用者的时候,必须在方法的参数列表后加throws+调用的类。可是刚才运行时异常在抛给调用者的时候并没有使用throws,因为运行时异常在抛出的时候可以将throws语句省略。
package com.jd.vo;
import com.jd.exception.AgeException;
public class Student {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) throws AgeException{
if (age>1 && age<30) {
this.age = age;
}else {
throw new AgeException("年龄无效");
}
}
}
也就是说,如果异常对象为运行时,则方法参数列表后面不使用throws也可以将异常抛给方法调用者,或者用try-cathc将异常自己处理;
如果异常对象为检查时,则方法参数列表后面必须使用throws抛出创建该对象的类,否则必须使用try-catch自己处理。
四.throw和throws比较
1.抛出的对象不同:
throw后面接的对象是具体产生的异常对象,而throws后面接的对象是将异常抛向的调用类;
2.使用位置不同:
throw一般用在方法体中,也可用在代码块中,而throws只能用在方法声明的参数列表后面;
要注意的是,当throw用在代码块中时,必须使用try-catch来解决该异常,因为代码块无法被调用,所以无法使用throws抛给其他类。
package com.jd.vo;
import com.jd.exception.AgeException;
public class Test {
{
try {
throw new AgeException("错误");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Student student = new Student();
student.setAge(100);
System.out.println(student.getAge());
}
}