卡片复位后持久化数组状态及对象头有效性技术问询
Java Card卡片复位后持久化数组的行为分析
嘿,这两个问题问到点子上了,刚好是Java Card开发里容易踩坑的细节,我来给你掰扯清楚:
问题1:卡片复位后,不同方式声明并初始化的持久化数组的变化
Java Card里数组的状态变化,核心得看数组的作用域(静态/实例)、初始化时机,以及复位后Applet的生命周期行为(仅执行构造方法,不执行processToolkit):
静态持久化数组(
static修饰,未标记transient):
静态变量属于类级别,而非Applet实例。卡片复位不会重新加载Applet类,所以这类数组的引用和内容都会保留复位前的状态——构造方法的调用不会影响它,因为静态变量只在类首次加载时初始化一次。实例级持久化数组(非
static、非transient,在构造方法/实例初始化块中初始化):
复位后会创建新的Applet实例,实例变量会重新执行初始化逻辑(比如private byte[] A = new byte[10];这种声明式初始化,会在构造方法执行前完成)。这意味着旧实例中的数组会失去引用,变成垃圾;新实例的数组是全新的对象,内容是构造时的初始值。实例级数组,仅声明、在
processToolkit中初始化:
复位后新的Applet实例只会执行构造方法,不会调用processToolkit,所以这类数组的引用会保持null,没有对应的数组对象;而旧实例中在processToolkit里创建的数组,会因为旧实例被销毁而变成垃圾。
问题2:代码中数组A、B、C的Object Header状态
先结合典型场景补全你给出的代码片段:
public class TestApplet extends Applet { private byte[] A = new byte[5]; // 实例变量,声明时初始化 private static byte[] B = new byte[5]; // 静态变量 private byte[] C; // 实例变量,仅声明,在processToolkit中初始化 public static void install(byte[] bArray, short bOffset, byte bLength) { new TestApplet(); } protected TestApplet() { register(); } public void processToolkit(APDU apdu) { C = new byte[5]; } }
针对复位后的状态:
- 数组A:新实例中的A是构造时全新创建的数组对象,它的Object Header处于有效状态;而旧实例中的A数组因为失去引用,对应的对象已变为垃圾。
- 数组B:作为静态变量,它指向的是类加载时创建的数组对象,复位后引用未变,这个数组的Object Header始终处于有效状态,内容也保留复位前的结果。
- 数组C:新实例中的C只是声明未初始化,没有对应的数组对象;旧实例中在
processToolkit里创建的C数组,因为旧实例被销毁,没有任何引用指向它,所以对应的对象已变为垃圾。
内容的提问来源于stack exchange,提问作者Vasanth
相关产品推荐
相关产品推荐

