如何使用Interface实例属性序列化类?得到NotSerializableException

Ada*_*gyi 3 java serialization android interface

我有一节课:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

和一个接口:

public interface MyInterface {
    void customFunction(int value);
}
Run Code Online (Sandbox Code Playgroud)

这个结构的目的是为了实现MyClass的每个实例的目的,可以有不同的customFunction(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
        }
    };
Run Code Online (Sandbox Code Playgroud)

但是,如果我想序列化MyClass的一个实例,我会得到NotSerializableException.

java.io.NotSerializableException:com.adamvarhegyi.duelsofcodrer.controller.MainActivity $ 1,java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344),位于java.io的java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651) .ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)位于java.io.ObjectOutputStream.defaultWriteObject的java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)java.io.ObjectOutputStream.defaultWriteObject上的java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959) ObjectOutputStream.java:360)java.io.ObjectOutputStream.write对话框中的java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651) )java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)at com.adamvarhegyi.duelsofcodrer.controller.MainActivity.onCreate(MainActivity.ja)va:62)在android.app.Anstrumentation.callActivityOnCreate(Instrumentation.java:1107)上的android.app.Activity.performCreate(Activity.java:6251)android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) Android.app.A活动时,Android.app.A活动,活动,移动活动(ActivityThread.java:2476),android.app上的android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1344)的android.app.ActivityThread.-wrap11(ActivityThread.java). Handler.dispatchMessage(Handler.java:102)位于android.app.Looper.loop(Looper.java:148)的android.app.ActivityThread.main(ActivityThread.java:5417),位于java.lang.reflect.Method.invoke (本地方法)com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

所以我的问题是我怎么能实现这个目标?如何使用Interface实例属性序列化类实例?

更新:

这是使代码更清晰的完整代码:

(我已经制作了内部课程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();
    }

}
}
Run Code Online (Sandbox Code Playgroud)

raf*_*elc 6

当您将类定义为a public class MyEntity implements Serializable时,基本上定义所有属性MyEntity应该是可序列化的.但是,MyInterface不是,因此,属性public MyInterface myInterface无法序列化,你得到了NotSerializableException.

要解决这个问题,你的界面应该是一个实例Serializable,所以它应该扩展它.

public interface MyInterface extends Serializable 
{
    void customFunction(int value);
}
Run Code Online (Sandbox Code Playgroud)

这样,MyEntity所有属性都可以序列化,并且不会抛出任何错误.重要的是要注意,所有的基本数据类型,比如是很重要的int,float等可序列化,以及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
    }
};
Run Code Online (Sandbox Code Playgroud)

你实际上正在创建一个全新的无名内部类来实现MyInterface.但是,由于这是一个内部类,它引用了它的父类Activity.Activity 不可序列化,所以这就是它抛出的原因NotSerializableException.

如何解决?

您无法创建可序列化的自定义类.但是,还有一条出路.

您可以创建一个新的类(如命名为CustomInterfaceImplementation一个单独的文件),并作出它的实例,或使内部类的你Activitystatic(请注意,此活动将不是你的内部创建onCreate()方法,因为这会不会使它应该在任何方法的范围之外和范围内创建Activity.

所以,举个例子,你可以这样:

CustomInterfaceImplementation customImpl = new CustomInterfaceImplementation();
myEntity.myInterface = customImpl;
Run Code Online (Sandbox Code Playgroud)

上面的代码可以工作,CustomInterfaceImplementation可以是你的一个静态类,也可以是MainActivity一个单独的公共java类.

但是,如果我想制作从obj到obj不等的移动课程怎么办?

正如我所说,制作全新的课程将会非常困难Serializable.但是,您可以在所有可能的实现之间提取所有公共代码,并且只传递可能变化的变量.这样,你就可以保持这种Serializable特性,并且可以实现你的目标.