Java Card Technology for Smart Card's Architecture and Programmer's Guide (Zhiqun Chen)翻译版(PART 6)

第 6章 Java 卡例外和例外处理  


一个例外就是在一个程序的执行过程中中断指令正常流程的事件。在 Java 语言中,例外是很重要
的,因为它们提供了一种处理程序错误的极好方法。 
 
Java 卡平台支持全部关于例外的 Java 语言编程结构。Java卡 applet 能够利用关键字 throw、try、
catch,或 finally,并且它们像在 Java平台一样地运行。 
 
当检测到内部运行时的问题时, JCRE 或 Java 卡虚拟机就抛出例外,或者由 applets 通过程序抛出。
尽管 Java  卡平台具有对 Java-风格例外的全部支持,但是在用法上有所不同,这是由于智能卡的有限
制的环境所造成的。这一章介绍 Java 卡平台中的一些例外,并讨论 applet 如何抛出和处理例外。 
 
6.1. java.lang 包中的例外  
     一般来说,Java 卡平台并不支持在 Java 技术核心包中可见的全部例外类型,因为其中有许多在智
能卡环境中并不能用。例如,在 Java 卡平台中不支持线程,并且因此和线程有关的例外就都不支持。  
 
然而,的确 Java 卡的 java.lang 包支持该包的 Java版本中的某些例外类。在所有支持的例外类中,
仅提供从根类 Object 中继承的 equals 方法和一个无参数的构造方法。表 6.1 列出了在java 卡平台上的
java.lang 包中的全部例外类。 


类Throwable定义了Java卡平台中所有例外类的共同祖先。这个类还保证java卡例外和它们的Java
平台的对应者具有相同的语意。例如,applets只能抛出和捕获从 throwable 类繁衍下来的对象。 
 
类 Exception是从 Throwable 类扩展而来的。正如在 Java 平台那样,它是 Java 卡平台中所有可检
测的例外的根类。类 RuntimeException 是从 Exception 类衍生来的,它是 Java 卡平台中所有非检测例
外的根类。检测与非检测例外的概念已在 java语言规范中予以定义。我们在下一节中也给出它们的定
义。 
 
表 6.1 中的其它类都是非检测例外。java.lang 包中的例外类提供了关于 Java 例外架构的基本语言
支持。当因 Java 语言违例而发生错误时,由 Java卡虚拟机抛出这些例外。 
 
6.2.Java 卡例外  
Java 卡平台提供了关于检测例外与非检测例外的类继承层次,如图 6.1所示。 


 
待检测的例外(Checked exception)是 Exception类的子类并且必须要么在 throwing 方法中捕获,
或者在方法头的 throws 子句中声明。这个要求是 Java 编译程序强制的。所有的 Java 卡待检测例外都
是从类 CardException 扩展而来的,而后者是从类 Exception 派生的。 

 
由于两个原因,所有待检测的例外最终必须由 applet  捕获。第一,待检测的例外表示 applet 中的
一个编程错误,因此必须由该 applet 纠正。第二,待检测的例外是对一个方法的接口的重要部分。这
就是为什么 applet  API 方法要在 throws 子句中指出待检查的例外(留给 applet  去处理)。所以如果
applet 没有捕获待检测的例外,Java编译程序就发出一个出错指示。 


    非检查例外(Unchecked exception)(常称为运行时例外)是类 RuntimeException  的子类,并且既
不需要在程序中捕获,也不用在 theows 子句中声明。非检测例外通常表示不可预料的运行时问题、编
程错误,或错误的 APDU处理状态。这样的例外是由 JCRE的最外层捕获的。Java卡平台中的所有非
检测例外都应从类 CardRuntimeException 扩展而来,后者是从类 RuntimeException 扩展来的。 
 
     我们为什么需要类CardException和CardRuntimeException呢?因为它们能够使一种节省资源的机
制成为可能,即一个例外对象能被重用多次,如 6.2.1 和 6.2.2 节所述。 
       
6.2.1.Java 卡例外原因码  
    
Java 例外类提供指示具体错误的“消息”串。在 Java 卡平台中不支持 String 类,所以在例外中不
能提供消息串。作为把一些额外的信息附加到例外上的另一种方法,Java 卡例外类采用一种数字型的
原因码。原因码被用来描述与该例外抛出有关的任选细节。原因码的类型为 short。 
 
原因码被定义为类 CardException 和 CardRuntimeException中的一个域,并因此由它们的子类所继
承。另外,这两个类都定义了两个 public  的 accessor方法(getReason和 setReason),以索取与设置原
因码。 
 
6.2.2.在 Java卡平台中抛出例外  
 
为了抛出一个 Java 系统的例外,applet 要建立一个例外类的一个实例,代码编写如下: 

 
    throw new MyException(“a specific error message”); 
 
当然,每当在 Java 卡平台中抛出一个例外,你就可能要建立一个新的例外对象。不过,存储空间
的经济利用总是智能卡中的一个值得关心的问题。如果每当抛出一个例外,applet  就要建立一个对象,
那么随着时间的推移,这个 applet  就会在珍贵的 EEPROM  存储器中积攒很多不用的例外实例。为了
优化存储器的使用,所有的例外对象都应当在初始化时建立,并把它们的引用永久地保存起来。当一
个例外事件发生的时候,就不用再建立新的例外对象了。applet 可照下面这样作: 
 
1.  索取并重用关于所希望例外对象的引用 
2.  在该对象中填入原因码 
3.  抛出该对象 
 
为了支持可重用的例外对象,JCRE已经为 Java卡 APIs 中的每一种例外类型建立了一个实例。类
CardException 和 CardRuntimeException 和它们的每一个子类,为使 applet  能重用该例外实例,提供
了一个静态方法 throwIt: 
 
               public static void throwIt(short reason) 
 
每当调用方法 throwIt 的时候,它就抛出一个 JCRE  已经建立的例外实例。Applet  向 throwIt  方
法指出一个原因码。例如,为了拒绝一个 APDU命令,applet  可抛出一个 ISOException 例外并指出原
因码为“命令不允许”: 
 
          ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); 
 
一个 applet也可以建立它自己的例外对象。在初始化过程中,applet 实例化这样的一个例外对象,
并将其引用保存在一个永久域中。以后,只要它需要抛出该例外时,就重用这个实例。 
 
6.2.3.ISOException.  
 
ISOException 是 Java 卡平台中一个特别的非检测例外。它是在运行期间发生的,指出一个警告或
卡片中的一个错误状态。ISOException 在原因码中封装了一个 ISO7816相应状态字。 
 
ISOException 允许 applet 高效地处理错误。当一条命令被成功地处理了的时候,方法正常返回。
但是如果发生错误,该方法就简单地抛出一个具有适当状态字的 ISOException 例外。 
 
一般地,applet 不处理 ISOException 例外。JCRE 最终捕获 ISOException 例外并返回一个它所包
含的原因码,作为向 host应用返回的 ISO状态字。这就使为什么该例外类在其名字中含有 ISO的原因。  
 
ISO 状态字是 APDU 协议的一部分。它被用作一个智能卡应用向 host 应用返回对一条 APDU 命
令处理的状态。Java 卡平台提供了一个接口 javacard.framework.ISO7816,定义了最通用的关于 ISO 
7816-3和 ISO 7816-4 的状态字常数。一个 applet能够定义它自己的状态字并可利用 ISOException 把它
们传送给 host 应用。 
 
6.2.4.UserException.  
 当一个 applet 遇到一个需要该 applet纠正的程序错误的时候,它就抛出一个 UserException。不
像 ISOException,UserException 例外是从 CardException 衍生出来的待检测的例外,因此必须由 applet
处理。如果 applet 需要建立另外的例外类型,它就建立从 UserException 派生的类。 
 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值