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

时间:2016-03-06 18:58:36

标签: java android serialization 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;
    }
}

接口:

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

这个结构的目的是为了实现的目的,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
        }
    };

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

  

java.io.NotSerializableException:   com.adamvarhegyi.duelsofcodrer.controller.MainActivity $ 1 at   java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)   在   java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)   在   java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)   在   java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)   在   java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)   在   java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)   在   java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)   在   java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)   在   java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)   在   java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)   在   java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)   在   com.adamvarhegyi.duelsofcodrer.controller.MainActivity.onCreate(MainActivity.java:62)   在android.app.Activity.performCreate(Activity.java:6251)at   android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)   在   android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)   在   android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)   在android.app.ActivityThread.-wrap11(ActivityThread.java)处   android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1344)   在android.os.Handler.dispatchMessage(Handler.java:102)at   android.os.Looper.loop(Looper.java:148)at   android.app.ActivityThread.main(ActivityThread.java:5417)at   java.lang.reflect.Method.invoke(Native Method)at   com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)   在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();
    }

}
}

2 个答案:

答案 0 :(得分:6)

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

要解决此问题,您的界面应该是public interface MyInterface extends Serializable { void customFunction(int value); } 的实例,因此它应该扩展它。

MyEntity

这样,int将所有属性都可序列化,并且不会抛出任何错误。请务必注意所有基本数据类型(例如floatStrings等)都可以序列化,以及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

如何解决这个问题?

您无法创建自定义类来转发,它们是Serializable 。但是,还有一条出路。

您可以在单独的文件中创建一个新类(例如名为Activity),并创建它的实例,或者创建static的内部类onCreate()(请注意,此活动不会在Activity方法中创建,因为这没有任何意义。应该在任何方法的范围之外和CustomInterfaceImplementation customImpl = new CustomInterfaceImplementation(); myEntity.myInterface = customImpl; 范围内创建

因此,例如,您可以拥有类似的内容:

CustomInterfaceImplementation

以上代码可行,MainActivitySerializable中的静态类或单独的公共java类。

但是如果我想制作从obj到obj不等的移动课程呢?

正如我所说,制作全新的Serializable课程将会非常困难。 HOWEVER ,您可以提取所有可能实现之间的所有公共代码,并且只传递可能变化的变量。这样,您就可以保持let config = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("my-id") self.session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.task = self.session!.downloadTaskWithURL(NSURL(string:self.currentDownloadModel!.downloadUrl)!) task!.resume() 特征,并且可以实现您的目标。

答案 1 :(得分:0)

使MyInterface可序列化,或者像myInterface一样添加瞬态:

exitmenu.lua

使myInterface瞬态标记变量不被序列化。