学习笔记,仅供参考,有错必纠
抛出异常
我们先用一个例子来说明这个事。
举个例子
我们对setAge方法进行改进,对于不合法的年龄,抛出Exception异常:
package com.guiyang.restudy3;
import com.guiyang.bean.Person;
public class D6Exception {
public static void main(String[] args) throws Exception {
Pig pig = new Pig("Tim", 9);
pig.setAge(-10);
}
}
class Pig {
private String name;
private int age;
public Pig() {
}
public Pig(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) throws Exception {
if (age > 0 && age <= 150) {
this.age = age;
} else {
throw new Exception("年龄不合法!");
}
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "[" + name + ", " + age + "]";
}
}
输出:
Exception in thread "main" java.lang.Exception: 年龄不合法!
at com.guiyang.restudy3.Pig.setAge(D6Exception.java:40)
at com.guiyang.restudy3.D6Exception.main(D6Exception.java:11)
如果在方法中,我们抛出一个编译时异常(比如Exception
),那么我们应该在方法上进行方法声明throws Excetion
,且在编译时,如果我们不对异常进行处理(即throws Exception
),那么就会出现编译时异常。
现在,我们对不合法的年龄,抛出运行时异常RuntimeException:
package com.guiyang.restudy3;
import com.guiyang.bean.Person;
public class D6Exception {
public static void main(String[] args) {
Pig pig = new Pig("Tim", 9);
pig.setAge(-10);
}
}
class Pig {
private String name;
private int age;
public Pig() {
}
public Pig(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
if (age > 0 && age <= 150) {
this.age = age;
} else {
throw new RuntimeException("年龄不合法!");
}
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "[" + name + ", " + age + "]";
}
}
输出:
Exception in thread "main" java.lang.RuntimeException: 年龄不合法!
at com.guiyang.restudy3.Pig.setAge(D6Exception.java:37)
at com.guiyang.restudy3.D6Exception.main(D6Exception.java:9)
注意!如果在方法中,我们抛出一个运行时异常,则在方法声明上不需要对异常进行处理,编译时,也不会报报错。
throw和throws的区别
- throws
- 用在方法声明后面,跟的是异常类名;
- 可以跟多个异常类名,用逗号隔开;
- 表示抛出异常,由该方法的调用者来处理。
- throw
- 用在方法体内,跟的是异常对象名;
- 只能抛出一个异常对象名;
- 表示抛出异常,由方法体内的语句处理。
finally关键字的特点及作用
- finally的特点
- 被finally控制的语句体一定会执行
- 特殊情况:在执行到finally之前jvm退出了(比如
System.exit(0)
)
- finally的作用
- 用于释放资源,在IO流操作和数据库操作中会使用到。
- 举个例子
package com.guiyang.restudy3;
public class D7Finally {
public static void main(String[] args) {
try {
System.out.println(10/0);
} catch (Exception e) {
System.out.println("除数为0");
} finally {
System.out.println("我执行了~");
}
System.out.println("-------");
try {
System.out.println(10/2);
} catch (Exception e) {
System.out.println("除数为0");
} finally {
System.out.println("我执行了~");
}
}
}
输出:
除数为0
我执行了~
-------
5
我执行了~
我们试着在第一个catch中增加一条return;
语句,看一看程序执行情况:
package com.guiyang.restudy3;
public class D7Finally {
public static void main(String[] args) {
try {
System.out.println(10/0);
} catch (Exception e) {
System.out.println("除数为0");
return;
} finally {
System.out.println("我执行了~");
}
System.out.println("-------");
try {
System.out.println(10/2);
} catch (Exception e) {
System.out.println("除数为0");
} finally {
System.out.println("我执行了~");
}
}
}
输出:
除数为0
我执行了~
可以看到,第一个try-catch-finally
中finally
语句体里的语句依然被执行了,但是第2个try-catch-finally
都没被执行,这是因为return语句相当于是方法的最后一口气,在它die之前,会看看这个try-catch-finally
中的finally
语句体中是否有要执行的语句,如果有,则会执行finally
中的语句后,再停止运行。
但是,如果我们在catch中退出Java虚拟机,那么就执行不到finally语句了:
package com.guiyang.restudy3;
public class D7Finally {
public static void main(String[] args) {
try {
System.out.println(10/0);
} catch (Exception e) {
System.out.println("除数为0");
System.exit(0);;
} finally {
System.out.println("我执行了~");
}
}
}
输出:
除数为0