throws的方式处理异常
* 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。
* 那么就通过throws在方法上标识。
throw
* 在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
先定义一个Person类:
public class Demo1_Exception {
public static void main(String[] args){
Person p = new Person();
p.setAge(-17);
System.out.println(p.getAge());
}
}
class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age >0 && age <= 150) {
this.age = age;
}else {
System.out.println("输入年龄有误");
}
}
}
输出结果:
输入年龄有误
0
现在在else里面抛出一个异常,再在主方法里面也抛出一个异常(鼠标放在异常位置Ctrl+1)
public class Demo1_Exception {
public static void main(String[] args)throws Exception{
Person p = new Person();
p.setAge(-17);//下面throws Exception后这里出错了
//因为这里在调用异常的方法,所以要么try,要么抛,这里我们选择抛,ctrl+1抛出异常主方法throws Exception将异常抛给虚拟机
System.out.println(p.getAge());
}
}
class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception{
if(age >0 && age <= 150) {
this.age = age;
}else {
throw new Exception("年龄非法");//添加这句的时候要在方法上加个方法声明,throws Exception抛出异常
}
}
}
输出结果
Exception in thread "main" java.lang.Exception: 年龄非法
at Test.Person.setAge(Demo1_Exception.java:38)
at Test.Demo1_Exception.main(Demo1_Exception.java:7)
现在我们把抛出的异常改为RuntimeException
public class Demo1_Exception {
public static void main(String[] args) {
Person p = new Person();
p.setAge(-17);
System.out.println(p.getAge());
}
}
class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) /*throws RuntimeException*/ {
if(age >0 && age <= 150) {
this.age = age;
}else {
throw new RuntimeException("年龄非法");
}
}
}
可以发现主方法不抛出异常的时候不报错,因为RuntimeException 是一个运行时异常,在编译的时候是不用对他进行处理的.所以在setAge方法上不抛出异常也是可以的.这也说明:
- 编译时异常的抛出必须对其进行处理
- 运行时异常的抛出可以处理也可以不处理
throws和throw的区别:
a:throws
* 用在方法声明后面,跟的是异常类名
* 可以跟多个异常类名,用逗号隔开
* 表示抛出异常,由该方法的调用者来处理
b:throw
* 用在方法体内,跟的是异常对象名
* 只能抛出一个异常对象名
* 表示抛出异常,由方法体内的语句处理
关于throw跟的是异常对象名拿上述代码中的setAge方法来讲:
public void setAge(int age) throws Exception,RuntimeException{ //这里Exception,RuntimeException无先后顺序
if(age >0 && age <= 150) {
this.age = age;
}else {
Exception e = new Exception("年龄非法");
throw e;//注意只能抛出一个对象
//throw new Exception("年龄非法");
}
练习
键盘录入一个int类型的整数,对其求二进制表现形式
* 如果录入的整数过大,给予提示,录入的整数过大请重新录入一个整数BigInteger
* 如果录入的是小数,给予提示,录入的是小数,请重新录入一个整数
* 如果录入的是其他字符,给予提示,录入的是非法字符,请重新录入一个整数
分析
* 1,创建键盘录入对象
* 2,将键盘录入的结果存储在String类型的字符串中,存储int类型中如果有不符合条件的直接报错,无法进行后续判断
* 3,键盘录入的结果转换成int类型的数据,是正确的还是错误的
* 4,正确的直接转换
* 5,错误的要进行对应判断
代码如下:
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
while(true) { //用while(true)录入错误之后程序不会停止
String line = sc.nextLine(); //将键盘录入的结果存储在line中
try {
int num = Integer.parseInt(line); //将字符串转换为整数
System.out.println(Integer.toBinaryString(num));//将整数转换为二进制
break; //跳出循环
}catch(Exception e) {
try {
new BigInteger(line); //匿名对象,看line是否能存进BigInteger
System.out.println("录入错误,您录入的是一个过大整数,请重新输入一个整数:");
}catch (Exception e2) { //alt + shif + z (try catch快捷键)
try {
new BigDecimal(line);
System.out.println("录入错误,您录入的是一个小数,请重新输入一个整数:");
} catch (Exception e1) {
System.out.println("录入错误,您录入的是非法字符,请重新输入一个整数:");
}
}
}
}
sc.close();//释放内存
}
}
这里有个快捷键:
选中下面代码之后alt+shift+z可生成try…catch:
new BigDecimal(line);
System.out.println("录入错误,您录入的是一个小数,请重新输入一个整数:");