索迪教育
Java编程技术基础第五章 异常与垃圾收集索迪教育上章回顾
掌握类的静态成员
掌握 Math类
掌握 this关键字
掌握 final关键字
掌握抽象类的概念与实现
掌握接口的概念与实现
掌握封装类
掌握内部类的实现索迪教育我们的目标
掌握 Java 异常处理机制
掌握 Java 垃圾收集机制索迪教育什么是异常
运行时发生的错误称为异常。处理这些异常就称为异常处理。
一旦引发异常,程序将突然中止,且控制将返回操作系统。
发生异常后此前分配的所有资源都将保留在相同的状态,这将导致资源漏洞 。
索迪教育异常的产生异常的产生:运行错
数组越界
除零错
对不存在的文件进行操作
内存溢出
程序中主动产生
。。。。
索迪教育异常处理的目的
ERROR !!
为了避免程序因异常终止,我们需要在程序中处理这些异常。
索迪教育
Java异常处理基础
Java异常处理机制采用一个统一和相对简单的抛出和处理错误的机制。如果一个方法本身能引发异常,
当所调用的方法出现异常时,调用者可以捕获异常使之得到处理;也可以回避异常,这时异常将在调用的堆栈中向下传递,直到被处理。
索迪教育异常体系结构所有异常类型都是内置类 Throwable的子类用于 Java运行时系统来显示与运行时系统本身有关的错误用于用户程序可能捕获的异常,也是用来创建用户异常 类型子类的类。
Error类对象由 Java虚拟机生成并抛出;
Exception类对象由应用程序处理或抛出。
索迪教育常见异常及其用途 - 1
异常 说明
RuntimeException java.lang包中 多数异常的基类
ArithmeticException 算术错误,如除以 0
IllegalArgumentException 方法收到非法参数
ArrayIndexOutOfBoundsException 数组下标出界
NullPointerException 试图访问 null 对象引用
SecurityException 试图违反安全性
ClassNotFoundException 不能加载请求的类索迪教育常见的异常及其用途 - 2
异常 说明
AWTException AWT 中的异常
IOException I/O 异常的根类
FileNotFoundException 不能找到文件
EOFException 文件结束
IllegalAccessException 对类的访问被拒绝
NoSuchMethodException 请求的方法不存在
InterruptedException 线程中断索迪教育异常处理模型
由五个关键字 try,catch,throw,throws 和
finally 处理。
Java 中可用于处理异常的两种方式:
自行处理,可能引发异常的语句封入在 try 块内,
而处理异常的相应语句则封入在 catch 块内。
回避异常,在方法声明中包含 throws 子句,通知潜在调用者,如果发生了异常,必须由调用者处理。
索迪教育
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块中处理异常输出结果索迪教育多个 catch 块
单个代码片段可能会引起多个错误。
可提供多个 catch 块 分别处理各种异常类型 。
.,,
try{ }
catch(ArrayIndexOutOfBoundsException e){ }
catch(Exception e) { }
...
ArrayIndexOutOfBoundsException类为 Exception 类的子类,但是如果异常属于 ArrayIndexOutOfBoundsException类将执行第一个 catch 块,之后控制将转向 try/catch块之后的语句,所以始终不会执行第二个 catch 块。
索迪教育多个 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("不是数字! ");
}
}
}
输出结果索迪教育嵌套的 try - catch 块
有时,块的一部分引起一个错误,而整个块可能又引起另一个错误。 在此情况下,需要将一个异常处理程序嵌套到另一个中。
在使用嵌套的 try块时,将先执行内部 try 块,如果没有遇到匹配的 catch 块,则将检查外部 try 块的
catch 块。
索迪教育
finally 块
确保了在出现异常时所有清除工作都将得到处理
与 try 块一起使用
无论是否出现异常,finally块都将运行
finally
catch 块 finally异常没有异常
try 块索迪教育
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);
}
}
输出结果索迪教育使用 throw
异常是通过关键字 throw 抛出,程序可以用 throw
语句引发明确的异常。如:
if(flag<0) {
throw new NullPointerException();
}
throw语句的操作数一定是 Throwable类类型或
Throwable子类类型的一个对象。
索迪教育使用 throws
如果一个方法可能导致一个异常但不处理它,此时要求在方法声明中包含 throws 子句,通知潜在调用者,
如果发生了异常,由调用者处理。
一个 throws子句列举了一个方法可能引发的所有异常类型。
这对于除 Error 或 RuntimeException 及它们子类以外类型的所有异常是必要的。
索迪教育使用 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方法的调用函数中捕获并处理异常索迪教育用户自定义的异常
内置异常不可能始终足以捕获所有错误,因此需要用户自定义的异常类
用户自定义的异常类应为 Exception 类(或者
Exception 类的子类)的子类
创建的任何用户自定义的异常类都可以获得
Throwable类定义的方法
class ArraySizeException extends NegativeArraySizeException{
ArraySizeException() {
super(“您传递的是非法的数组大小,);
}
}
该类是 Exception
的子类索迪教育使用用户自定义的异常示例
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])); }
}
输出结果索迪教育异常的生命周期异常将沿调用链一直前进,
直到被 捕获 或程序结束退出。
程序退出点
Exceptions
索迪教育垃圾收集机制
垃圾收集是将分配给对象但不再使用的内存回收或释放的过程,
例如一个对象没有指向它的引用或者其赋值为 null,
此对象将适于进行垃圾收集,
尽管可以从 System或 Runtime类通过调用 gc()方法来调用垃圾收集器,但并不能预测或保证垃圾收集在何时发生,
通过下列方式可关闭应用程序中的垃圾收集,
java -noasyncgc ……
索迪教育
finalize()方法
有时当撤消一个对象时,需要完成一些操作,例如,如果一个对象正在处理的是非 Java资源,如文件句柄或
window字符字体,这时要确认在一个对象被撤消以前要保证这些资源被释放,为处理这样的情况,Java提供了被称为收尾 (finalization)的机制,可用于在控制返回操作系统前完成清除过程,
索迪教育
finalize()方法 -续一
实现这种机制非常简单,只要为类定义 finalize()方法即可,Java回收该类的一个对象时,就会调用这个方法,在 finalize()方法中,要指定一个对象被撤消前必须执行的操作,垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用,就在对象被释放之前,Java运行系统调用该对象的 finalize()
方法,
其语法为,
Protected void finalize() throws Throwable
注意,引用不能进行垃圾收集,只有对象才能进行垃圾收集,
索迪教育
finalize()方法 -续二
例如,
Object a = new Object();
Object b = a;
a = null;
索迪教育
finalize()方法 -续三
在 Java中,对象的撤消和其 finalize()方法的调用之间几乎没有联系,对象执行完毕,并不显示撤消对象,而是在没有任何引用的时候,将对象标志为不再使用,因此,
程序员无法确切的知道何时何地调用 finalize().甚至执行 gc()调用垃圾收集器时,也不能保证立即执行
finalize()方法,
索迪教育
gc()方法使用
class GCDemo
{
public static void main(String[] args)
{
int i;
long a;
Runtime r = Runtime.getRuntime();
Long[] values = new Long[200];
System.out.println("空闲的内存大小为 " + r.freeMemory());
for(a=10000,i=0;i<200;a++,i++)
{
values[i] = new Long(a);
}
System.out.println("创建数组后的空闲的内存大小为 " + r.freeMemory());
for(i=0;i<200;i++)
{
values[i]=null;
}
r.gc(); //垃圾收集
System.out.println("垃圾收集后的空闲的内存大小为 " + r.freeMemory());
}
}
索迪教育本章小结
掌握 Java 异常处理机制
掌握 Java 垃圾收集机制