Parcelable遇到IOException写入枚举包含的方法

时间:2015-01-05 01:24:36

标签: java android serializable

有一个枚举:

public static enum CheckResult {
    NONEEDTOUPDATE, 
    FORCEUPDATE, 
    OPTIONALUPDATE;

    public boolean hasNewVersion() {
        return this != NONEEDTOUPDATE;
    } 
}

并将其放入另一个类:

public static class UpdateData implements Serializable {
    public static final String BUNDLE_KEY = "UpdateData";
    private static final long serialVersionUID = 7956542923164822779L;
    public String apkDownloadUrl;
    public String newVersionName;
    public CheckResult checkResult;
}

并使用bundle发送它:

Intent intent = new Intent(context, UpdateActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable(UpdateData.BUNDLE_KEY, data);//data is an UpdateData instance
intent.putExtras(bundle);
context.startActivity(intent);

会导致异常。

logcat的:

java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.tencent.game3366.update.UpdateChecker$UpdateData)
android.os.Parcel.writeSerializable(Parcel.java:1323)
android.os.Parcel.writeValue(Parcel.java:1271)
android.os.Parcel.writeArrayMapInternal(Parcel.java:618)
android.os.Bundle.writeToParcel(Bundle.java:1692)
android.os.Parcel.writeBundle(Parcel.java:643)
android.content.Intent.writeToParcel(Intent.java:7410)
android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2297)
android.app.Instrumentation.execStartActivity(Instrumentation.java:1437)
android.app.Activity.startActivityForResult(Activity.java:3516)
android.app.Activity.startActivityForResult(Activity.java:3477)
android.support.v4.app.FragmentActivity.startActivityForResult(Unknown Source)
android.app.Activity.startActivity(Activity.java:3719)
android.app.Activity.startActivity(Activity.java:3687)

如果我只是将枚举改为:

public static enum CheckResult {
    NONEEDTOUPDATE, 
    FORCEUPDATE, 
    OPTIONALUPDATE 
}

一切都好,为什么会这样?

更新

当我重建整个项目时,没有异常发生............我应该说什么......

1 个答案:

答案 0 :(得分:-1)

与C ++不同,Java枚举不是基于整数的值。它本质上是一个类,每个枚举“value”作为此类的单例实例。因此,不是像C ++那样比较基础整数值,而是在做类似

之类的事情时真正比较对象身份的平等性。

A.VALUE_A == A.VALUE_B

当你进行enum comparsion时。此外,这样的枚举类实例是在初始化阶段构造的,这意味着你总是可以使用实例。

现在,如果枚举是可序列化的,这意味着它可以从流中去除,那么您将遇到典型的序列化单例问题。一旦你将枚举实例反序列化到主内存中,你就会在内存中有2个这样的实例副本,上面的比较和你所有其他的枚举结构,比如EnumMap等,都不再存在基于实例相等(==)和系统hashCode()(如果使用SUN / Oracle JVM,则基本上是System.identityHashCode()用于默认实现。)

上述问题是在语言层面避免 - 这就是为什么你不能宣布Enum来实施Serializable