You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

卡片复位后持久化数组状态及对象头有效性技术问询

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:56:25