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

时间:2016-05-15 10:57:14

标签: java serialization

我正在试验命令模式,在wikipedia中使用它就像这样:

  

网络

     

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

我假设这里发送对象意味着在对象的字段内发送数据,对吧?而不是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对我有意义,但为什么不是第一次来?它是否在一些缓存(或Metaspace)中存储通过lambda创建的第一个类?

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

1 个答案:

答案 0 :(得分:1)

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