我正在试验命令模式,在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
实现。
答案 0 :(得分:1)
它不是将实现存储在文件中。为了表明这一点,将代码分成两个类:一个是序列化的,一个是反序列化的,和在不同的环境中执行它们,而这些环境中没有另一个.class文件。