【问题标题】:Java serialization read enum to stringJava序列化读取枚举到字符串
【发布时间】:2019-12-18 20:25:09
【问题描述】:

有一些遗留的 Java pojos 用于二进制序列化。在一个 pojo 的字段中,我有一个枚举字段。现在在新的 Java pojo 中,枚举字段被替换为字符串字段。

// old pojo with enum
class Test {
    private DataType dataType;
    private String someOtherField;
}

enum DataType {
    Int,
    Float,
    String
}

// new pojo without enum field
class NewTest {
    private String dataType;
    private String someOtherField;
}

在读取(反序列化)旧数据时,我使用了这里提到的技术 - https://stackoverflow.com/a/14608062/314310 将旧数据读入新重构的 pojo,它对非枚举字段成功执行。但是将枚举数据读取到字符串字段似乎几乎是不可能的。我得到了例外

java.lang.ClassCastException:无法将 demo.DataType 的实例分配给 demo.NewTest 实例中 java.lang.String 类型的字段 demo.NewTest.dataType

有没有我可以做到这一点?

编辑:

这是我的自定义ObjectInputStream的代码

class MyObjectInputStream extends ObjectInputStream {
    private static final Map<String, Class<?>> migrationMap = new HashMap<>();

    static {
        migrationMap.put("demo.Test", NewTest.class);
        migrationMap.put("demo.DataType", String.class);
    }

    public MyObjectInputStream(InputStream stream) throws IOException {
        super(stream);
    }

    @Override
    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
        ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();

        for (final String oldName : migrationMap.keySet()) {
            if (resultClassDescriptor != null && resultClassDescriptor.getName().equals(oldName)) {
                Class<?> replacement = migrationMap.get(oldName);

                try {
                    resultClassDescriptor = ObjectStreamClass.lookup(replacement);
                } catch (Exception e) {
                    log.error("Error while replacing class name." + e.getMessage(), e);
                }
            }
        }

        return resultClassDescriptor;
    }
}

【问题讨论】:

  • 你能打印你的转换器类吗?因为您引用的代码(来自答案)不会从一种类型(枚举)到另一种类型(字符串)进行任何转换。我想你的问题在这里:f.set(resultClassDescriptor, replacement); 其中替换是 DataType Java 期望一个字符串。
  • @NoDataFound 用代码编辑了我的问题。

标签: java serialization enums deserialization


【解决方案1】:

尝试将您的枚举更改为:

enum DataType {
    Int,
    Float,
    String;

    public static DataType getFromString(String stringDataType) {
        for(DataType dataType in DataType.values()) {
            if (dataType.toString().equals(stringDataType)) {
                return dataType;
            }
         }
         throw new IllegalArgumentException("Invalid input");
    }
}

因此,当您想将 Enum 分配给您调用的 String 时:

newTest.dataType = test.dataType.toString();

当你想将字符串分配给 Enum 时,你调用:

test.dataType = DataType.getFromString(newTest.dataType);

【讨论】:

  • 总有 DataType.valueOf(String) 为此,特别是如果 toString() 没有被覆盖。
  • 我认为你是对的。我没有使用编译器检查这一点。 xD
猜你喜欢
  • 2012-02-27
  • 2014-08-10
  • 2011-01-08
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 2019-11-28
相关资源
最近更新 更多