当前位置: 首页 > 知识库问答 >
问题:

如何序列化具有接口实例属性的类?获取NotSerializableException

周马鲁
2023-03-14

我有一节课:

public class MyEntity implements Serializable {

    public MyInterface myInterface;

    public String name;
    public int    value;

    public MyEntity(String name, int value) {
        this.name = name;
        this.value = value;
    }
}

和接口:

public interface MyInterface {
    void customFunction(int value);
}
MyEntity myEntity = new MyEntity("My entity", 100);
    myEntity.myInterface = new MyInterface() {
        @Override
        public void customFunction(int value) {
            //This is my custom function.
            //This can be different for every instance of MyEntity class
        }
    };

这是完整的代码,让它更清晰:

(我从MyEntityMyInterface创建了内部类,使其更加简化。)

package com.adamvarhegyi.duelsofcodrer.controller;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

import com.adamvarhegyi.duelsofcodrer.R;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class MainActivity extends Activity {

public interface MyInterface extends Serializable {
    void customFunction(int value);
}

public class MyEntity implements Serializable {

    public MyInterface myInterface;

    public String name;
    public int    value;

    public MyEntity(String name, int value) {
        this.name = name;
        this.value = value;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    MyEntity myEntity = new MyEntity("My entity", 100);

    myEntity.myInterface = new MyInterface() {
        @Override
        public void customFunction(int value) {
            //This is my custom function.
            //This can be different for every instance of MyEntity class
        }
    };


    //Trying to serialize
    try {
        FileOutputStream fos = openFileOutput("myfile", Context.MODE_PRIVATE);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(myEntity);
        oos.close();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}
}

共有1个答案

戚良弼
2023-03-14

当您将类定义为公共类时,MyEntity实现了Serializable,您基本上定义了MyEntity的所有Atribute都应该是可序列化的。但是,MyInterface不是,因此,public MyInterface属性不能序列化,您将得到NotSerializableException

为了解决这个问题,您的接口应该是serializable的一个实例,所以它应该扩展它。

public interface MyInterface extends Serializable 
{
    void customFunction(int value);
}

这样,myEntity将具有可序列化的所有属性,并且不会抛出任何错误。需要注意的是,所有基本数据类型(如intfloat等)以及strings都可以序列化。

经过反复思考、反复阅读代码,我发现了您的问题。当您执行以下操作时:

myEntity.myInterface = new MyInterface() {
    @Override
    public void customFunction(int value) {
        //This is my custom function.
        //This can be different for every instance of MyEntity class
    }
};

您实际上正在创建一个全新的无名内部类,它实现了MyInterface。但是,由于这是一个内部类,因此它引用了其父类activity。活动不可序列化,因此它会抛出NotSerializableException

怎么解决?

CustomInterfaceImplementation customImpl = new CustomInterfaceImplementation();
myEntity.myInterface = customImpl;

正如我所说的,创建serializable的全新类是很困难的。然而,您可以提取所有可能实现之间的所有公共代码,并只传递可能发生变化的变量。这样,您就可以保持serializable特性,并且可能能够实现您的目标。

 类似资料:
  • 我按照本指南将Micronaut Serialization与Jackson注释一起使用。当我创建一个抽象类和一个类时,我可以使用和来正确序列化类的对象。 但是,当我使用类型的属性序列化的对象但使用运行时类型时,该属性被序列化为。 下面的代码应该解释了我的问题。请注意,我正在使用,当我将其替换为时,它会按预期工作。 有没有一种方法可以使用注释使其工作?

  • 我正在用Python制作一个基于文本的RPG,并尝试设置地图和玩家移动。然而,我还没有弄清楚如何“链接”房间,以便玩家可以使用诸如北、南等命令从一个房间无缝移动到另一个房间。 我正在使用一个名为“Room”的类,它具有x坐标和y坐标属性。我已经制作了地图中每个“瓷砖”的实例,具有特定的x-pos和y-pos值。我要做的是根据当前的x-pos或y-pos是什么,转到“Room”类的当前实例。但是,我

  • 问题内容: 我正在使用Jackson的反序列化包含接口作为其属性之一的对象的JSON表示。可以在此处看到代码的简化版本: https://gist.github.com/sscovil/8735923 基本上,我有一个具有两个属性的类:和。JSON模型如下所示: 该属性被定义为所谓的接口,我有实现它的几个类(例如,)。这个想法是图像文件与文档文件等具有不同的属性(高度,宽度)。 我在工作过的例子这

  • 我以前问过这个问题,但现在我试图获得XQuery计算的序列化属性,而不是XSLT转换。 使用此代码: 原始问题答案中提出的方法似乎不适用于这里,因为我无法从XQueryEvaluator实例化序列化程序,而getDeclaredSerializationProperties只能在XSLT上下文中使用。 我用的是萨克森10他。

  • 大家好,我需要序列化一个带有字典的对象的响应,动态地离开了json示例。我试图在一个c#类中序列化这个响应对象(request_validator),但这不起作用,请谁能帮助我,有什么想法吗?对不起我的英语谢谢

  • 我有以下XSL样式表: 我正在使用Saxon 9.9对其进行如下转换。 我希望返回值是样式表中指定的“UTF-8”,但它返回null。(序列化程序实例似乎根本没有属性。)这是为什么?获取输出属性的正确方法是什么?