- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个类:
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;
}
}
还有一个接口(interface):
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) at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959) at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360) at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054) at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384) at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461) at com.adamvarhegyi.duelsofcodrer.controller.MainActivity.onCreate(MainActivity.java:62) at android.app.Activity.performCreate(Activity.java:6251) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at 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) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
所以我的问题是我怎样才能做到这一点?我如何序列化具有接口(interface)实例属性的类实例?
更新:
这是完整的代码,以使其更清晰:
(我从 MyEntity
和 MyInterface
中创建了内部类,以使其更加简化。)
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();
}
}
}
最佳答案
当您将类定义为 public class MyEntity implements Serializable
时,您基本上是在定义 MyEntity
的所有属性都应该是可序列化的。但是,MyInterface
不是,因此,属性 public MyInterface myInterface
无法序列化,您会得到 NotSerializableException
。
要解决这个问题,您的界面应该是 Serializable
的实例,因此它应该扩展它。
public interface MyInterface extends Serializable
{
void customFunction(int value);
}
这样,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
}
};
您实际上是在创建一个全新的 nameless 内部类,它实现了 MyInterface
。但是,由于这是一个内部类,它会引用其父类 Activity
。 Activity 不可可序列化,因此它会抛出 NotSerializableException
。
如何解决?
您将无法创建可序列化的自定义待办类。但是,有一条出路。
您可以在一个单独的文件中创建一个新类(例如命名为 CustomInterfaceImplementation
),并创建它的实例,或者创建一个您的 Activity
的内部类,它是static
(请注意,此 Activity 不会在您的 onCreate()
方法内创建,因为这没有任何意义。它应该在任何方法范围之外和内部创建Activity
范围)。
所以,例如,你可以有这样的东西:
CustomInterfaceImplementation customImpl = new CustomInterfaceImplementation();
myEntity.myInterface = customImpl;
上面的代码可以作为 CustomInterfaceImplementation
MainActivity
中的static 类或单独的公共(public) java 类。
但是如果我想制作随 obj 到 obj 不同的移动类怎么办?
正如我所说,制作可序列化
的全新类是很困难的。 但是,您可以提取所有可能实现之间的所有通用代码,并且只传递可能会发生变化的变量。这样,您将保持 Serializable
特性,并可能实现您的目标。
关于java - 如何使用接口(interface)实例属性序列化类?得到 NotSerializableException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35831117/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!