问题引入:
创建学生类:
public class Student{//student类
private int age;
public void setAge(int age) {
if(age>0&&age<15) {
this.age=age;
}else {
System.out.println("年龄无效");
}
}
public int getAge() {
return age;
}
}
创建测试类:
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setAge(100);
System.out.println(student.getAge());
}
}
因为age属性在Student中为私有属性,当Test操作age时为公共方法操作私有属性。
思考:当Test对age赋值时,不满足Student的要求,System.out.println(“年龄无效”);输出提示错误的信息,但对于程序员来说,这种单纯的输出提示无法定位程序哪个地方出错。
通过throw实现异常定位:
public class Student{//student类
private int age;
public void setAge(int age) {
if(age>0&&age<15) {
this.age=age;
}else {
//System.out.println("年龄无效");
throw new NullPointerException("年龄无效");
}
}
public int getAge() {
return age;
}
}
此时执行代码,控制台会精准输出出现异常的位置和原因,便于我们维护。但此时输出的异常是空指针异常,我们期望报错的是年龄异常,也就是词不达意。这时就需要我们自己创建一个异常类,用来描述年龄异常。
自定义异常类:
Why?
Java中提供的异常类无法准确描述当前发生的异常,此时就要自定义异常类。
How?
创建继承Exception或其子类的自定义类;
自定义类要实现本身的有参构造方法(通常是含有一个String类型参数的构造方法);
public class AgeException extends RuntimeException{
public AgeException(String msg) {
super(msg);
}
}
此时执行代码时,就会在控制台上输出异常的类型和位置。这对于协作开发有很大的帮助。
解决异常的方法:
向外抛出:
public class Student{//student类
private int age;
public void setAge(int age) {
if(age>0&&age<15) {
this.age=age;
}else {
//System.out.println("年龄无效");
throw new AgeException("年龄无效");
}
}
public int getAge() {
return age;
}
}
此时将异常抛给调用者,至于调用者如何解决就与我们无关了
try-catch捕获(将异常抛给自己):
public class Student {// student类
private int age;
public void setAge(int age) {
if (age > 0 && age < 15) {
this.age = age;
} else {
try {
throw new AgeException("年龄无效");
} catch (AgeException e) {
e.printStackTrace();
}
}
}
public int getAge() {
return age;
}
}
throw
1.如果异常对象属于运行时异常类,则:
方法参数列表后可以不使用throws(这种情况下默认有throws),不使用try-catch。也能将异常抛给方法调用者。例:
public class Student {// student类
private int age;
public void setAge(int age) {
if (age > 0 && age < 15) {
this.age = age;
} else {
throw new AgeException("年龄无效");
}
}
public int getAge() {
return age;
}
}
public class AgeException extends **RuntimeException**{
public AgeException(String msg) {
super(msg);
}
}
2.如果异常对象属于检查时异常类时,则:
使用throw抛出异常时,需要在参数列表后面使用throws抛出创建该对象的类或使用try-catch进行捕获异常。例:
使用try-catch:
public class Student {// student类
private int age;
public void setAge(int age) {
if (age > 0 && age < 15) {
this.age = age;
} else {
try {
throw new AgeException("年龄无效");
} catch (AgeException e) {
e.printStackTrace();
}
}
}
public int getAge() {
return age;
}
}
public class AgeException extends **Exception**{
public AgeException(String msg) {
super(msg);
}
}
使用throws:
public class Student {// student类
private int age;
public void setAge(int age) {
if (age > 0 && age < 15) {
this.age = age;
} else {
throw new AgeException("年龄无效");
}
}
public int getAge() {
return age;
}
}
public class AgeException extends **Exception**{
public AgeException(String msg) {
super(msg);
}
}
区别:
抛出的东西不同:
throw抛出的是具体的异常对象
throws抛出的是异常类
使用位置不同:
throw一般用于方法体中或代码块中,在代码块中,如果抛出的是检查时异常类创建的对象,只能使用try-catch(throws用于方法参数列表之后)
throws:只能用在方法参数列表后面
注意:
自定义创建的类若继承RuntimeException,则该类创建的对象就属于运行时异常;
若直接继承Exception,则该类创建的对象属于检查时异常。