java 技术及其应用赵锐pdf_Java技术及应用

增强性能类

Java有很多类是用于提高性能的,如异常处理、并发和反射等,本章将介绍Java的这些增强性能类。

5.1 异 常 处 理

Java语言采用“异常(exception)”来为其程序提供错误处理能力,异常是一个事件,当执行中的程序中断其正常的指令流时出现;Java代码能检测出错误,向运行系统指明是什么错误,抛出一个异常。通常,抛出的事件使线程终止,显示其错误信息。如果想自己处理异常,可以用一个catch语句捕获异常。

5.1.1 异常

异常实际上是异常事件的简称,许多不同的错误可以引起异常。有硬件错误,如硬盘坏了;有编程错误,如试图访问越界数组元素。若这些错误出现在Java的方法中,该方法创建一个异常对象,对象中包含异常类型、错误出现时程序的状态等信息,交到运行系统,这叫抛出一个异常。

运行系统负责找出处理错误的方法,它往回搜索方法调用栈(call stack),直到找出一个合适的异常处理器,所谓合适,是指抛出的异常类型与异常处理器处理的类型相同。选择异常处理器称为捕获异常,若运行系统找不到合适的异常处理器,系统就终止运行。

用异常处理错误有三个优点。

(1)处理错误的代码与正常代码分开。

这样做既不会影响正常代码的逻辑结构,而且还可以知道哪一步出现错误,并分清楚出错后要做的事情。

(2)沿调用栈向上传送错误。

Java的方法可以避开它抛出的异常,由它上一层调用方法处理。只有关心错误的方法才检测错误,其他方法可以声明一个throws子句,把错误往上传。

(3)按错误类型和错误区别分组。

异常可以分类成组,例如,处理数组时的一些错误(下标超出数组范围,插入数组的元素类型不对,所搜索的元素不在数组中等)可以归为一组。Java的异常都是对象,异常分组是类与子类的自然结果。

异常必须是Throwable型,即是Throwable类与子类的实例。Throwable类在java.lang包中定义,其继承关系如图5-1所示。

图5-1 Throwable类的继承关系

从图5-1中可见,Throwable是Object的子类,它本身又有两个子类Error和Exception。

(1)Error是动态链接失败或虚拟机出现“硬”失效后出现的,由虚拟机抛出。普通的Java 程序不会抛出Error,也不需要捕获它。

(2)Exception表明出现了问题,但不是严重的系统问题。大多数程序都可以抛出和捕获它。Java包中定义了许多Exception的后继类,指明各种类型的异常。例如, IllegalAccessException表明不能访问某个方法;InstantiationException表明程序试图实例化一个抽象类或接口。

Exception可分为运行时刻异常(RuntimeException)和非运行时刻(Non-runtime)异常。

① RuntimeException是Exception的一个重要子类,代表运行时刻出现在Java 虚拟机的异常,包括算术异常(如被零除)、指针异常(如试图通过null引用访问对象)和下标异常(如用太大或太小的下标访问数组元素)等,表5-1列出了这类异常中常见的类型。

表5-1 运行系统抛出的RuntimeException

运行系统抛出的RuntimeException

含义

ArithmeticException

除以零

NullPointerException

试图访问空对象的变量和方法

IncompatibleClassChangeException

类变化后将影响该类其他对象对方法和变量的引用,那些对象没有重编译

ClassCastException

不正确的类转换

NegativeArraySizeException

数组的长度为负数

OutOfMemoryException

执行new操作,但没有多余内存空间给该对象

NoClassDefFoundException

引用一个类,但系统找不到它

IncompatibleTypeException

试图实例化一个接口,可抛出

ArrayIndexOutOfBoundsException

试图引用数组中的非法元素,可抛出

UnsatisfiedLinkException

一个native方法在运行时不能链接,可抛出

InternalException

不可抛出,代表运行系统本身的问题

运行时刻异常在程序中到处可出现,数量很多,检查它们所花的代价超过了捕捉与声明带来的好处,因此编译器不要求捕捉或声明运行时刻异常(RuntimeException)。

② 非运行时刻(Non-runtime)异常代表合法操作所调用方法必须知道的有用信息,例如磁盘满了、没有访问权限等,非运行时刻异常必须抛出或捕获。

5.1.2 捕获与声明的要求

Java语言要求各方法捕获或声明(declare)在方法的作用范围内可能抛出的所有非运行时刻(Non-runtime)异常。如果编译器检查到某个方法没有满足要求,它会显示出错信息,并拒绝编译程序。例如,源程序中有一句:

while (System.in.read()!=-1)

用到了I/O操作read(),可能会出现IOException,如果程序中没有catch部分,就要在方法的声明部分用throws子句说明可以抛出它,如:

public static void main(String args[]) throws java.io.IOException {

...

}

这样编译程序才认可,否则会出现下列出错信息:

warning: Exception java.io.IOException must be caught,or it must be declared in throws clause of this method.

为什么方法不捕获异常时就要声明会抛出异常? 因为方法抛出的任何异常实际上是该方法的公共编程接口的一部分,方法的调用者必须知道该方法抛出的异常,以便决定如何处理这些异常。

5.1.3 处理异常

异常可以分类成组,Throwable类加上子类就构成一组,如Exception类是Throwable的子类,本身又有一个子类ArrayException,而ArrayException又有InvalidIndexException、ElementTypeException 和 NoSuchElementException三个子类。这三个子类都是具体的错误类型。方法可以捕获具体类型的错误,例如:

catch (InvalidIndexException e) {

...

}

ArrayException代表一组异常,方法也可以按组捕获异常,例如:

catch (ArrayException e) {

...

}

例5.1进一步说明如何处理异常。

【例5.1】 异常示例。

import java.io.*;

import java.util.Vector;

class ListOfNumbers {

private Vector victor;

final int size=10;

public ListOfNumbers() {

int i;

victor=new Vector<> (size);

for (i=0; i  victor.addElement(new Integer(i));

} //构造方法,创建向量victor,包含10个整数0~9

public void writeList() {

PrintStream pStr = null;

System.err.println("Entering try statement");

int i;

pStr=new PrintStream(new BufferedOutputStream(new

FileOutputStream("OutFile.txt")));

for (i=0; i  pStr.println("Value at:"+i+"="+victor.elementAt(i));

pStr.close();

} //将一列数字写入文本文件OutFile.txt

public static void main(String[] args) {

// TODO Auto-generated method stub

ListOfNumbers lofn = new ListOfNumbers();

lofn.writeList();

}

}

程序的运行结果如图5-2所示。

图5-2 例5.1的运行结果

分析:该类可能出现两个异常:第1个是IOException,由FileOutputStream("OutFile. txt")构造方法打不开该文件时抛出;第2个是ArrayIndexOutOfBoundsException,由victor. elementAt(i)遇到过大或过小的i时抛出。编译时编译器会指出要抛出IOException异常的信息,但不会指出要抛出ArrayIndexOutOfBounds异常,因为前者属于非运行时刻异常,后者是运行时刻异常,Java只要求处理非运行时刻异常。

建造一个异常处理器处理上述异常,由三个部分组成:try块、catch块和finally块。

……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值