Java 如何序列化和恢复函数列表?
我想创建一个函数列表,我将来可以运行它 首次上市:Java 如何序列化和恢复函数列表?,java,function,serialization,Java,Function,Serialization,我想创建一个函数列表,我将来可以运行它 首次上市: import java.io.*; import java.util.ArrayList; class ExampleF implements Serializable{ interface Executable extends Serializable{ void execute(); } ArrayList<Executable> alFunc = new ArrayList<>();
import java.io.*;
import java.util.ArrayList;
class ExampleF implements Serializable{
interface Executable extends Serializable{ void execute(); }
ArrayList<Executable> alFunc = new ArrayList<>();
public static void main(String[] args) throws IOException, ClassNotFoundException {
ExampleF ex1 =new ExampleF();
Executable exec1 =new Executable() {
@Override
public void execute() { System.out.println("exec func1"); }
};
Executable exec2 =new Executable() {
@Override
public void execute() { System.out.println("exec func2"); }
};
ex1.alFunc.add(exec1);
ex1.alFunc.add(exec2);
ex1.alFunc.get(0).execute();
ex1.alFunc.get(1).execute();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data1.dat"));
oos.writeObject(ex1);
oos.close();
System.out.println("after loading:");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data1.dat"));
ExampleF ex2 = (ExampleF) ois.readObject();
ois.close();
ex2.alFunc.get(0).execute();
ex2.alFunc.get(1).execute();
}
}
但是,当我尝试使用仅使用序列化信息来清除加载时,我得到ClassNotFoundException,例如$1
:
import java.io.*;
import java.util.ArrayList;
class ExampleF implements Serializable{
interface Executable extends Serializable{ void execute(); }
ArrayList<Executable> alFunc = new ArrayList<>();
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data1.dat"));
ExampleF ex2 = (ExampleF) ois.readObject();
ois.close();
ex2.alFunc.get(0).execute();
ex2.alFunc.get(1).execute();
}
}
import java.io.*;
导入java.util.ArrayList;
类ExampleF实现可序列化{
接口可执行文件扩展可序列化{void execute();}
ArrayList alFunc=新的ArrayList();
公共静态void main(字符串[]args)引发IOException,ClassNotFoundException{
ObjectInputStream ois=新ObjectInputStream(新文件InputStream(“data1.dat”));
examplefex2=(ExampleF)ois.readObject();
ois.close();
ex2.alFunc.get(0.execute();
ex2.alFunc.get(1.execute();
}
}
我怎样才能解决这个问题
- 创建必要函数的多个列表
- 连载
- 以后只能在使用only execute()下载所需文件后使用它
另外,我使用Java7(如果有必要,可以升级到Java8)。
您会遇到这个问题,因为exec1和exec2是在main方法范围内创建的匿名类。您必须将它们转换为普通类、静态嵌套类或至少应将它们定义为静态变量,如下所示:
public class ExampleF implements Serializable {
interface Executable extends Serializable { void execute(); }
ArrayList<Executable> alFunc = new ArrayList<>();
private static Executable exec1 =new Executable() {
@Override
public void execute() { System.out.println("exec func1"); }
};
private static Executable exec2 =new Executable() {
@Override
public void execute() { System.out.println("exec func2"); }
};
...
public类示例实现可序列化{
接口可执行文件扩展可序列化{void execute();}
ArrayList alFunc=新的ArrayList();
私有静态可执行文件exec1=新可执行文件(){
@凌驾
public void execute(){System.out.println(“exec func1”);}
};
私有静态可执行文件exec2=新可执行文件(){
@凌驾
public void execute(){System.out.println(“exec func2”);}
};
...
之所以会出现此问题,是因为exec1和exec2是在主方法范围内创建的匿名类。必须将它们转换为普通类、静态嵌套类,或者至少应将它们定义为静态变量,如下所示:
public class ExampleF implements Serializable {
interface Executable extends Serializable { void execute(); }
ArrayList<Executable> alFunc = new ArrayList<>();
private static Executable exec1 =new Executable() {
@Override
public void execute() { System.out.println("exec func1"); }
};
private static Executable exec2 =new Executable() {
@Override
public void execute() { System.out.println("exec func2"); }
};
...
public类示例实现可序列化{
接口可执行文件扩展可序列化{void execute();}
ArrayList alFunc=新的ArrayList();
私有静态可执行文件exec1=新可执行文件(){
@凌驾
public void execute(){System.out.println(“exec func1”);}
};
私有静态可执行文件exec2=新可执行文件(){
@凌驾
public void execute(){System.out.println(“exec func2”);}
};
...
看看这篇博文。您使用的是匿名类-
如果仔细查看示例#1和#2中的匿名类,您会发现#1中存在的匿名类在#2中不存在。在这种情况下,JVM将无法找到该类。看看这篇博文。您使用的是匿名类-
如果仔细查看示例#1和#2中的匿名类,您会发现#1中存在的匿名类在#2中不存在。在这种情况下,JVM将无法找到该类。谢谢,我尝试过。但是,在本例中,我应该能够在第二个示例中描述所有私有静态内部类(仅限反序列化和函数运行代码)。我希望代码紧凑(不描述函数),我想从序列化文件中获取函数的代码。或者我得到本地类不兼容的异常:stream classdesc serialVersionUID=....@Joysi您要做的事情要复杂得多,您需要序列化类内容并依赖特定的类加载器来加载类。也许最简单的方法是使用RMI当它开箱即用时,请勾选此项。我知道没有标准方法可以序列化函数的Java字节码,并可能进一步反序列化。作为ArrayList的可执行项。谢谢,我尝试过。不过,在本例中,我应该能够在第二个示例中描述所有私有静态内部类(仅限反序列化和函数运行代码)。我希望代码紧凑(不描述函数),我想从序列化文件中获取函数的代码。或者我得到本地类不兼容的异常:stream classdesc serialVersionUID=....@Joysi您要做的事情要复杂得多,您需要序列化类内容并依赖特定的类加载器来加载类。也许最简单的方法是使用RMI由于它是开箱即用的,请勾选此项。我知道没有标准方法可以序列化函数的Java字节码,并可能进一步反序列化。作为ArrayList的可执行项。谢谢。我知道匿名函数。我不知道如何绕过它,并大致决定。还有什么其他反序列化方法没有任何描述的函数列表(在类等中)?从序列化的文件就绪代码下载。我想保持代码的第二部分不变:ObjectInputStream ois=new ObjectInputStream(new FileInputStream(“data1.dat”);ExampleF ex2=(ExampleF)ois.readObject();ois.close();ex2.alFunc.get(0.execute();ex2.alFunc.get(1.execute());这就是问题所在。匿名类的标识与声明的父类绑定在一起。现在,如果您希望这些类仍然可用,您需要以某种方式将这些类放到类路径中。您可能正在编写自己的类加载器,从不同的位置加载所选类。谢谢。我知道匿名函数。我不知道如何绕过它并做出一般性决定。还有什么方法可以反序列化没有任何描述的函数列表(在类等中)?从序列化的文件就绪代码下载。我希望保持代码的第二部分不变:ObjectInputStream ois=new ObjectInput