欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java异常中的throw和throws

程序员文章站 2022-07-14 11:28:03
...

简单的封装:

在类中的成员变量,如果是public修饰的,则不容易限制其他类中对其操作的范围,此时为了限制一个与需求相对应的合理范围,就可以用封装。

//例:
public class Student {
	private int age;//声明一个私有成员属性age
	public void setAge(int age){
		if(age>0 && age<28){
			this.age=age;
		}else{
			System.out.println("无效");
		}
	}//定义一个公共方法对age进行赋值,且限定范围
	public int getAge(){
		return age;
	}//定义一个公共方法得到age的值
}
public class Test{
	public static void main(String [] args){
		Student student=new Student();
		student.setAge(40);//对age进行不符合要求操作
		System.out.println(student.getAge());//得到当前age值
	}
}
/*运行结果:
  无效
  0*/
  • 通过上述实例,我们发现封装可以有效的对操作进行规范。
  • 但是,在其他人得到“失效”后,不知道原因,不知道源代码在哪里

这时我们可以使用throw抛出一个异常

throw(抛出异常对象)

public void setAge(int age){
	if(age>0 && age<28){
		this.age=age;
	}else{
		throw new NullPointerException("无效");//抛出一个空指针异常对象
	}
}//改写原Student类中的setAge方法
/*Test类不变运行结果:
Exception in thread "main" java.lang.NullPointerException: 无效
	at Student.setAge(Student.java:10)
	at Test.main(Test.java:7)*/
  • throw关键字可以抛出一个异常对象,这时我们可以在控制台看到,所在语句的位置。
  • 但是,很明显这种限制方式并不是产生了空指针异常,而是为了抛出一个异常而选择空指针。

为了使这个过程更符合情理且更容易准确辨别,我们可以构造一个自定义异常类。

自定义异常类

  • 延续上例,我们自定义一个AgeException类
public class AgeException extends RuntimeException{
	private static final long serialVersionUID = -1337582885342407212L;
	public AgeException(String message) {
		super(message);
	}//调用父类有参构造方法(本例这一个就够,如果需要可以多选或定义)
}//AgeException继承运行时异常类,可用父类方法
  • 这时候,我们就有一个自定义的异常,AgeException(年龄异常)。此时,我们再去改写Student类setAge方法
public void setAge(int age){
	if(age>0 && age<28){
		this.age=age;
	}else{
		throw new AgeException("无效");//抛出一个年龄异常对象(通常异常类独在一个包中,这时这里需要引包)
	}
}
/*Test类不变运行结果:
Exception in thread "main" exception.AgeException: 无效
	at Student.setAge(Student.java:12)
	at Test.main(Test.java:7)*/
  • 这时,进行错误操作时,就能清楚是什么错,在哪,该怎么做。

那么,如果需要一个检查时异常呢?

throws

我们可以将AgeException该为检查时异常类,我们知道,Exception下非运行时异常都为检查时异常,所以我们只需要让AgeException继承Exception即可,此时AgeException和RuntimeException为Exception的同级子类。

public class AgeException extends Exception{     //继承Exception类
	private static final long serialVersionUID = -1337582885342407212L;
	public AgeException(String message) {
		super(message);
	}
}// AgeException类改为检查时异常类

此时我们会发现,Student类中,抛出异常语句已经报错,因为检查时异常只有两种处理方式:
①一直上抛(将异常抛给方法调用者)到Jvm;
②在Jvm前,程序通过try、catch解决掉。

  • 如何上抛:
    改写Student类setAge方法
public void setAge(int age){
	if(age>0 && age<28) throws  AgeException{//抛出检查时异常类
		this.age=age;
	}else{
		throw new AgeException("无效");
	}
}
  • 如果方法要上抛出一个异常类,则:
    在方法参数列表()后,方法体{}前写:throws 异常类名1,异常类名2,…

  • 此处我们也可以直接在抛出后,直接解决异常,即在setAge方法中,直接使用try、catch:

public void setAge(int age){
	if(age>0 && age<28) throws  AgeException{//抛出检查时异常类
		this.age=age;
	}else{
		try {
				throw new AgeException("无效");
		} catch (AgeException e) {
				e.printStackTrace();
		}
	}
}

这种情况下,异常已经解决。

  • 如果选择将异常上抛到Test类main函数中,则要么继续抛出异常类给Jvm(例1)、或者将异常在main函数中解决掉(例二)。
//例一
public class Test{
	public static void main(String [] args) throws AgeException {//抛出存在检查时异常类
		Student student=new Student();
		student.setAge(40);//检查时异常
		System.out.println(student.getAge());
	}
}
//例二
public class Test{
	public static void main(String [] args){
		Student student=new Student();
		try {
			student.setAge(40);
		} catch (AgeException e) {
			e.printStackTrace();
		}//使用try、catch解决异常
		System.out.println(student.getAge());
	}
}

throw与throws的区别:

  • throw用于抛出异常对象:
    1、如果异常对象为运行时,则方法参数列表后面可以不是使用throws,也可以将异常抛给方法调用者;try、catch
    2、如果异常对象为检查时,则方法参数列表后面必须使用throws抛出创建该对象的类;如果没有throws 必须try-catch
  • 抛出的东西不同:throw抛出的是具体的异常对象,而throws抛出的是抽象的异常类;
  • 使用位置不同:throw一般用在方法体中,也可用在代码块中,但是如果抛出的是检查时异常类创建的对象,则必须使用try-catch自行处理;throws只能用在方法声明括号后面;