Version 3.0
异常和垃圾收集第五章
2
回顾
类中的静态成员属于类。
final 修饰符可应用于类、方法和变量。
定义抽象类的目的是提供可由其子类共享的一般形式。
接口就是需要由其他类实现的行为模板。
访问控制级别,public,protected,缺省、
private
封装类就是封装基本数据类型的类 。
内部类指嵌入外部类内的类。
3
目标
了解异常的定义
了解异常的分类
掌握 try,catch 和 finally 语句的用法
掌握 throw,throws子句的用法
掌握如何定义自己的异常
了解 Java 的垃圾收集机制
4
什么是异常
运行时发生的错误称为异常。处理这些异常就称为异常处理。
一旦引发异常,程序将突然中止,且控制将返回操作系统。
发生异常后此前分配的所有资源都将保留在相同的状态,这将导致资源漏洞 。
5
Java异常处理基础
Java异常处理机制采用一个统一和相对简单的 抛出和处理 错误的机制。如果一个方法本身能 引发 异常,当所调用的方法出现异常时,调用者可以 捕获 异常使之得到处理;也可以 回避 异常,这时异常将在调用的堆栈中向下传递,直到被处理。
6
异常体系结构所有异常类型都是内置类 Throwable的子类用于 Java运行时系统来显示与运行时系统本身有关的错误用于用户程序可能捕获的异常,也是用来创建用户异常 类型子类的类。
Error类对象由 Java虚拟机生成并抛出;
Exception类对象由应用程序处理或抛出。
7
常见异常及其用途 2-1
异常 说明
RuntimeException java.lang包中 多数异常的基类
ArithmeticException 算术错误,如除以 0
IllegalArgumentException 方法收到非法参数
ArrayIndexOutOfBoundsException 数组下标出界
NullPointerException 试图访问 null 对象引用
SecurityException 试图违反安全性
ClassNotFoundException 不能加载请求的类
8
常见的异常及其用途 2-2
异常 说明
AWTException AWT 中的异常
IOException I/O 异常的根类
FileNotFoundException 不能找到文件
EOFException 文件结束
IllegalAccessException 对类的访问被拒绝
NoSuchMethodException 请求的方法不存在
InterruptedException 线程中断
9
异常处理模型
由五个关键字 try,catch,throw,throws
和 finally 处理。
Java 中可用于处理异常的两种方式:
– 自行处理,可能引发异常的语句封入在 try
块内,而处理异常的相应语句则封入在 catch
块内。
– 回避异常,在方法声明中包含 throws 子句,
通知潜在调用者,如果发生了异常,必须由调用者处理。
10
try - catch 块示例
public class ExceptionDemo {
public static void main(String args[]) {
try {
int c= calculate(9,0);
System.out.println(c);
}
catch (Exception e) {
System.err.println("发生异常," + e.toString());
e.printStackTrace();
}
}
static int calculate(int a,int b) {
int c = a/b; return c;
}
}
调用函数 calculate,
将引发一个异常在 catch块中处理异常输出结果
11
多个 catch 块
单个代码片段可能会引起多个错误。
可提供多个 catch 块 分别处理各种异常类型 。
.,,
try{ }
catch(ArrayIndexOutOfBoundsException e){ }
catch(Exception e) { }
...
ArrayIndexOutOfBoundsException类为 Exception 类的子类,但是如果异常属于 ArrayIndexOutOfBoundsException类将执行第一个 catch 块,之后控制将转向 try/catch块之后的语句,所以始终不会执行第二个 catch 块。
12
多个 catch 块示例
class Catch22 {
public static void main(String args[]) {
try {
String num=args[0];
int numValue=Integer.parseInt(num);
System.out.println("平方为 "+numValue*numValue);
}
catch(ArrayIndexOutOfBoundsException ne) {
System.out.println("未提供任何参数 ! ");
}
catch(NumberFormatException nb) {
System.out.println("不是数字 ! ");
}
}
}
输出结果
13
嵌套的 try - catch 块
有时,块的一部分引起一个错误,而整个块可能又引起另一个错误。 在此情况下,
需要将一个异常处理程序嵌套到另一个中。
在使用嵌套的 try块时,将先执行内部 try 块,
如果没有遇到匹配的 catch 块,则将检查外部 try 块的 catch 块。
14
finally 块
确保了在出现异常时所有清除工作都将得到处理
与 try 块一起使用
无论是否出现异常,finally块都将运行
finally
catch 块 finally异常没有异常
try 块
15
finally 块 示例
class FinallyDemo {
int no1,no2;
FinallyDemo(String args[]) {
try {
no1 = Integer.parseInt(args[0]);
no2 = Integer.parseInt(args[1]);
System.out.println("相除结果为 "+no1/no2);
}
catch(ArithmeticException i) {
System.out.println("不能除以 0");
}
finally {
System.out.println("Finally 已执行 ");
}
}
public static void main(String args[]) {
new FinallyDemo(args);
}
}
输出结果
16
使用 throw
异常是通过关键字 throw 抛出,程序可以用 throw语句引发明确的异常。如:
try {
if(flag<0){
throw new NullPointerException();
}
}
throw语句的操作数一定是 Throwable类类型或 Throwable子类类型的一个对象。
17
使用 throws
如果一个方法可能导致一个异常但不处理它,
此时要求在方法声明中包含 throws 子句,
通知潜在调用者,如果发生了异常,由调用者处理。
一个 throws子句列举了一个方法可能引发的所有异常类型。
这对于除 Error或 RuntimeException及它们子类以外类型的所有异常是必要的。
18
使用 throws示例
class ThrowsDemo{
static void throwOne() throws IllegalAccessException{
System.out.println("在 throwOne中,");
throw new IllegalAccessException("非法访问异常 ");
}
public static void main(String args[]){
try{
throwOne();
}
catch(IllegalAccessException e){
System.out.println("捕获 "+e);
}
}
}
在该方法中没有处理异常,只是声明可能引发的异常在 throwOne方法的调用函数中捕获并处理异常
19
用户自定义的异常
内置异常不可能始终足以捕获所有错误,
因此需要用户自定义的异常类
用户自定义的异常类应为 Exception 类
(或者 Exception 类的子类)的子类
创建的任何用户自定义的异常类都可以获得 Throwable类定义的方法
class ArraySizeException extends NegativeArraySizeException{
ArraySizeException() {
super(“您传递的是非法的数组大小,);
}
}
该类是 Exception
的子类
20
使用用户自定义的异常示例
class UserExceptionDemo {
int size,array[];
UserExceptionDemo(int s) {
size = s;
try { checkSize(); }
catch(ArraySizeException e) {System.out.println(e);}
}
void checkSize() throws ArraySizeException {
if(size < 0) throw new ArraySizeException();
array = new int[size];
for(int i = 0; i < size; i++) {
array[i] = i+1;
System.out.print(array[i]+" ");
}
}
public static void main(String arg[]) {
new UserExceptionDemo(Integer.parseInt(arg[0])); }
}
输出结果
21
垃圾收集 2-1
垃圾收集是可将分配给对象但不再使用的内存回收或释放的过程
Java 将自动释放不再使用的内存
如果一个对象没有指向它的引用或将其赋值为 null,则此对象将适于进行垃圾收集
22
垃圾收集 2-2
垃圾收集器将作为优先级低的单独线程运行
可通过下列方式关闭应用程序中的垃圾收集
java –noasyncgc …
如果关闭了垃圾收集,程序极有可能会因为内存在某个时刻耗尽而失败
23
使用 finalize 方法
Java 提供了一种与 C++ 语言中的析构器相似的方式,可用于在控制返回操作系统前完成清除过程
如果存在 finalize(),它将在垃圾收集前被执行一次,而且每个对象仅执行一次
protected void finalize() throws Throwable
可以建议垃圾收集,但并不能保证它何时会发生
24
总结 2-1
运行时发生的错误称为异常。
必须捕获引发的每个异常,否则应用程序不会正常中止。
异常处理允许在一个地方集中进行错误处理。这使得可以创建功能强大且健壮的代码。
Java 使用 try 和 catch 块来处理异常。 try
块中的语句引发异常,而 catch 块则处理异常。
25
总结 2-2
可以同时使用多个 catch 块来分别处理各种异常类型。
程序可以用 throw语句引发明确的异常。
关键字 throws 用于列出一个方法可能引发的异常类型。
不管是否发生了异常,都将执行 finally
块中的语句。
Java 中的垃圾收集就是将分配给对象但不再使用的内存回收或释放的过程。