通过文件/网络而不是仅通过数据传递对象实现



我在尝试命令模式,它在维基百科中的一个用法是这样的:

网络

可以通过网络发送整个命令对象,以便在其他机器上执行,例如计算机游戏中的玩家动作。

我假设这里发送对象意味着在对象的字段中发送数据,对吧?而不是execute()方法中的代码?

我正在通过序列化进行实验;发现了一种我无法解释的行为。这是程序:

public class Test {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("Commands"))) {
            Command command = () -> {
                System.out.println("MUHAHA!");
            };
            outputStream.writeObject(command);
        }
        try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("Commands"))) {
            Command command = (Command) inputStream.readObject();
            command.execute();
        }
    }
}
interface Command extends Serializable {
    void execute();
}

在执行时,我得到字符串MUHAHA!。因此,execute()方法的实现被保存在文件中。然而,如果我注释掉第一个try{}块&然后执行,它将失败。Commands文件保留了上次执行的内容,但未能读取&作语法分析

我得到以下堆栈跟踪:

Exception in thread "main" java.io.IOException: unexpected exception type
    at java.io.ObjectStreamClass.throwMiscException(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadResolve(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at random.Test.main(Test.java:18)
Caused by: java.lang.NoSuchMethodException: random.Test.$deserializeLambda$(java.lang.invoke.SerializedLambda)
    at java.lang.Class.getDeclaredMethod(Unknown Source)
    at java.lang.invoke.SerializedLambda$1.run(Unknown Source)
    at java.lang.invoke.SerializedLambda$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.lang.invoke.SerializedLambda.readResolve(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    ... 5 more

NoSuchMethodException对我来说有些道理,但为什么它不是第一次出现呢?它是否将通过lambda创建的第一个类存储在某个缓存(或元空间)中?

最后,是否可以发送一个实现?我希望在另一端,execute方法的代码将被写入一些动态创建的Command实现中。

它没有将实现存储在文件中。为了说明这一点,请将代码分为两个类:一个序列化,另一个反序列化,在不同的环境中执行它们,而这两个环境都没有另一个的.class文件。

最新更新