当前位置: 首页 > 面试题库 >

自定义枚举也是可序列化的吗?

夏侯博
2023-03-14
问题内容

我了解Enum是可序列化的。因此,这样做是安全的。(selectedCountry是enum Country

没有客户成员变量的原始枚举

public enum Country {
    Australia,
    Austria,
    UnitedState;
}

分段

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (savedInstanceState != null) {
        selectedCountry = (Country)savedInstanceState.getSerializable(SELECTED_COUNTRY_KEY);
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putSerializable(SELECTED_COUNTRY_KEY, selectedCountry);
}

但是,如果我在自定义枚举类中有不可序列化的成员,该怎么办?例如,

原始枚举客户成员变量

package org.yccheok;

import org.yccheok.R;

/**
 *
 * @author yccheok
 */
public enum Country {
    Australia(R.drawable.flag_au),
    Austria(R.drawable.flag_at),
    UnitedState(R.drawable.flag_us);

    Country(int icon) {
        this.icon = icon;
        nonSerializableClass = new NonSerializableClass(this.toString());
    }

    public int getIcon() {
        return icon;
    }

    public static class NonSerializableClass {
        public NonSerializableClass(String dummy) { this.dummy = dummy; }
        public String dummy;
    }

    private final int icon;

    public NonSerializableClass nonSerializableClass;
}

我测试了 有用。(我通过在序列化之前和之后打印出所有成员变量的值进行了测试。它们在前后均相同)

但是,我不明白为什么会起作用?
由于我没有提供适当的readObjectwriteObject,因此需要Serializable界面提供。

如有效Java 项目75:考虑使用自定义序列化表格所述
,如果我的枚举中有自定义成员变量,是否需要提供自己的readObjectwriteObject


问题答案:

之所以起作用,是因为的序列化过程Enum不同于其他类的序列化过程。从官方文档中:

1.12枚举常量的序列化

枚举常量的序列化与普通的可序列化或可外部化的对象不同。枚举常量的序列化形式仅由其名称组成;常量的字段值不存在于表单中。为了序列化枚举常量,ObjectOutputStream写入枚举常量的name方法返回的值。为了反序列化枚举常量,ObjectInputStream从流中读取常量名称。然后,通过调用java.lang.Enum.valueOf方法,将常量的枚举类型与接收到的常量名称作为参数传递,来获得反序列化的常量。像其他可序列化或可外部化的对象一样,枚举常量可以用作随后出现在序列化流中的反向引用的目标。

这意味着您所有的自定义字段 都不会 被序列化。在你的情况一切正常,因为你的应用程序仍在运行,并且您得到 相同的
Enum,你传递给实例savedInstanceState.putSerializable

但是,想象一下您的应用因为Android没有足够的内存而被杀死的情况。下次用户打开应用程序时,您将获得一个
Enum实例,并且所有自定义字段都将丢失,并由构造方法重新初始化。因此,枚举中的可变字段始终有效transient



 类似资料:
  • 问题内容: 遵循在使用GSON解析JSON时使用枚举中的建议,我正在尝试序列化其键是使用Gson 的映射。 考虑以下类别: 两个问题: 为什么打印而不是? 我该如何打印? 问题答案: Gson对密钥使用了专用的序列化器。默认情况下,它使用将要用作键的对象的。对于类型,基本上就是常量的名称。,默认为类型,仅当将序列化为JSON值(对名称除外)时才使用。 使用来构建你的实例。

  • 问题内容: 对于我正在从事的项目,我们使用了许多枚举。模型对象本身由许多微小的类组成。然后,通过该模型,我们通过JAXB将XML序列化为XML。现在,我们希望能够使用枚举中特定方法的返回序列化枚举值;给出: 等。目前,当序列化为XML时,我们得到如下信息: JAXB是如何处理它的。但是,我们需要将值作为getCode()的返回值,并且我们的许多枚举确实遵循该约定(具有用于通过代码进行查找的相应静态

  • 我正在分析SonarQube 5.1版的Java SE 7项目。 然后,我在下面的代码中面对squid:S1948。 “可序列化”类中的字段应该是瞬态的或可序列化的 Serializable类中的字段本身必须是可序列化的或瞬态的,即使该类从未显式序列化或反序列化。这是因为在负载下,大多数J2EE应用程序框架都会将对象刷新到磁盘,并且具有非瞬态、不可序列化数据成员的所谓可序列化对象可能会导致程序崩溃

  • 但有些时候我们需要控制枚举的类型,那么我们可以 Enum 派生出自定义类来满足这种需要。通过修改上面的例子: #!/usr/bin/env python3 # -*- coding: UTF-8 -*- from enum import Enum, unique Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Au

  • enum 关键字允许创建一个代表数个可能变量的数据的类型(原文:The enum keyword allows the creation of a type which may be one of a few different variants.若您对此句有 更好的翻译或理解,希望指出来,谢谢。)。在 struct 中任何合法的变量在 enum 同样是合法的。 // 隐藏未使用代码警告的属性。

  • 问题内容: 我有一个下面的枚举: 我用控制器()返回枚举数组,Spring将其序列化为以下json字符串: 强迫Jackson像POJO一样序列化枚举的最佳方法是什么?例如: 我使用了不同的注释,但无法获得这样的结果。 问题答案: 终于我找到了解决方案。 我必须用注释枚举并实现自定义序列化程序: