详述throw和throws

目录

 

一.封装

二.用throw

三.自定义异常

 四.throws的用法

四.throw和throws比较


一.封装

详情见博客: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());
	}
}

 详述throw和throws

但还是存在着一个问题,当项目的代码量非常大的时候,此处打印一个“年龄无效”,程序员要想找到哪里出问题就必须依次检查,会浪费大量时间,所以这个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,就会提示错误出在哪里了,这样的异常提示会大大提高了排错的效率:

详述throw和throws

但是在上段代码的修改中,使用的是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导入编号:

详述throw和throws

一个异常类就自定义完毕,最后得到的代码就是这样:

package com.jd.exception;

public class AgeException extends RuntimeException{

	private static final long serialVersionUID = -1829894057306300522L;

	public AgeException(String message) {
		super(message);
	}
}

这时再执行一次Test类得到的运行结果就是自定义的AgeException异常的提示了:

详述throw和throws

 四.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());
	}
}

 

上一篇:JavaScript之基本语句


下一篇:A. The Child and Homework