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

禁用Java序列化与IO流时,如何反序列化含可变长字符串的Flight类?

解决方案

因为禁止使用Java对象序列化工具和IO流类,我们可以通过自定义内存级的序列化/反序列化逻辑来处理source和destination这两个可变长度字符串,以下是几种实用方案:

方案一:基于长度前缀的字符串编码(最可靠)

这种方式通过先存储字符串的长度,再存储字符串内容,避免分隔符冲突问题,完全在内存中处理,不依赖任何IO流或序列化工具。

序列化逻辑(将字符串转成可解析的字节数组)

对于单个字符串:

  • 把字符串转成UTF-8字节数组
  • 将字节数组的长度(int类型,占4字节)转成字节序列
  • 拼接长度字节和字符串字节,得到最终的序列化结果

反序列化逻辑(从字节数组还原字符串)

  • 先读取前4字节,解析出字符串的字节长度
  • 再读取对应长度的字节,转成UTF-8字符串

代码示例

在Flight类中添加自定义方法:

import java.nio.charset.StandardCharsets;

public class Flight {
    // 原有字段、构造器、getters/setters不变...

    // 将source和destination序列化为字节数组(内存级操作)
    public byte[] serializeSourceDest() {
        byte[] sourceBytes = source.getBytes(StandardCharsets.UTF_8);
        byte[] destBytes = destination.getBytes(StandardCharsets.UTF_8);
        
        // 总长度:source长度(4字节) + source字节 + dest长度(4字节) + dest字节
        byte[] result = new byte[4 + sourceBytes.length + 4 + destBytes.length];
        
        // 写入source长度
        System.arraycopy(intToBytes(sourceBytes.length), 0, result, 0, 4);
        // 写入source字节内容
        System.arraycopy(sourceBytes, 0, result, 4, sourceBytes.length);
        
        int destStartIndex = 4 + sourceBytes.length;
        // 写入destination长度
        System.arraycopy(intToBytes(destBytes.length), 0, result, destStartIndex, 4);
        // 写入destination字节内容
        System.arraycopy(destBytes, 0, result, destStartIndex + 4, destBytes.length);
        
        return result;
    }

    // 从字节数组反序列化出source和destination
    public static String[] deserializeSourceDest(byte[] data) {
        // 解析source长度
        int sourceLen = bytesToInt(data, 0);
        // 还原source字符串
        String source = new String(data, 4, sourceLen, StandardCharsets.UTF_8);
        
        int destStartIndex = 4 + sourceLen;
        // 解析destination长度
        int destLen = bytesToInt(data, destStartIndex);
        // 还原destination字符串
        String destination = new String(data, destStartIndex + 4, destLen, StandardCharsets.UTF_8);
        
        return new String[]{source, destination};
    }

    // 辅助方法:int转4字节数组
    private static byte[] intToBytes(int value) {
        return new byte[]{
            (byte) (value >> 24),
            (byte) (value >> 16),
            (byte) (value >> 8),
            (byte) value
        };
    }

    // 辅助方法:从字节数组指定位置解析int
    private static int bytesToInt(byte[] bytes, int offset) {
        return ((bytes[offset] & 0xFF) << 24) |
               ((bytes[offset+1] & 0xFF) << 16) |
               ((bytes[offset+2] & 0xFF) << 8) |
               (bytes[offset+3] & 0xFF);
    }
}

方案二:基于特殊分隔符的字符串拼接(简单场景适用)

如果能确保source和destination中不会出现特定分隔符(比如###),可以直接用分隔符拼接字符串,反序列化时拆分即可:

序列化

public String serializeSourceDestStr() {
    return source + "###" + destination;
}

反序列化

public static String[] deserializeSourceDestStr(String data) {
    // 限制拆分次数,避免destination中意外包含分隔符导致解析错误
    return data.split("###", 2);
}

注意:如果字符串可能包含分隔符,这种方法会出错,优先选择方案一。

方案三:内存级JSON解析(适合复杂场景)

如果项目允许引入轻量JSON库(比如Gson),可以直接将source和destination转成JSON字符串,反序列化时解析,全程在内存中操作,不涉及IO流或Java序列化工具:

代码示例(用Gson)

import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class Flight {
    // 原有字段、构造器、getters/setters不变...

    public String serializeSourceDestJson() {
        JsonObject json = new JsonObject();
        json.addProperty("source", source);
        json.addProperty("destination", destination);
        return new Gson().toJson(json);
    }

    public static String[] deserializeSourceDestJson(String jsonStr) {
        JsonObject json = new Gson().fromJson(jsonStr, JsonObject.class);
        return new String[]{
            json.get("source").getAsString(),
            json.get("destination").getAsString()
        };
    }
}

内容的提问来源于stack exchange,提问作者tayron.vikranth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:09:28