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