有人能告诉我Java对象序列化的必要性,并举例说明需要的情况吗?(我已经了解什么是序列化,我只想了解何时使用它以及如何使用它)。
Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:
火星的科学家们正在等待完整付款。一旦付款完成,火星的科学家们将serialversionUID与地球的科学家们共享。地球的科学家将其设置为机器人类,然后一切开始运作。
更新
尽管借助序列化的帮助,他们能够使用信号而不是实际的宇宙飞船发送数据,但他们意识到发送大量数据仍然是一个挑战。序列化使过程更加便宜和快速,但仍然很慢。因此,不同的科学家提出了不同的想法来减小数据大小。一些科学家建议压缩数据,一些科学家建议使用不同的机制来表示数据,以便可以进行反序列化。其中一些想法包括XML、JSON、msgpack、Nimn
当需要发送数据或将其存储在文件中时,通常会使用序列化。这里的数据指的是对象而不是文本。
现在的问题是,网络基础设施和硬盘都是只理解位和字节而不理解JAVA对象的硬件组件。
序列化是将Java对象的值/状态转换为字节以便于发送或存储的过程。
这类比于你的语音如何通过PSTN电话线传输。
用法
既然你询问的是需求,而不仅仅是定义,那么就有很多用例:
简单地保存数据以供以后使用。例如,假设你正在编写一个视频游戏。你的程序不会永远运行;即使它从未崩溃(希望如此),用户也可能在某个时候退出程序,或者操作系统可能杀死程序以节省资源(例如,在Android上,用户没有交互的后台进程经常被操作系统故意杀死以回收系统资源,如RAM)。为了确保用户不从头开始,并且可以从之前的存档点或最近的存档点继续游戏,您需要将游戏状态写入持久存储(即硬盘、用户的Google Drive帐户等)。为此,您需要将表示游戏状态的内存中的数据结构转换为原始字节,然后写入磁盘(或任何其他系统)。
从远程服务器检索信息。让我们继续以游戏为例...假设您正在创建一个在线多人游戏,或者您想要使提供新级别或新物品变得可能,而无需用户更新其应用程序。为此,您希望有关在线玩家的信息或有关新级别/物品的信息从服务器计算机(您将其用作各种设备上安装的应用程序的所有副本的联系点)通信到应用程序的各个副本。服务器和应用程序都需要这些数据结构的某种内存表示形式(例如,其他玩家的位置、新级别的结构、新物品的描述/图像等),但是为了将信息从服务器传输到设备上的应用程序,通信系统由原始字节组成,因此需要一种方法将数据转换为原始字节,并从原始字节转换回有意义的内存数据结构。
当您想将对象的状态保存到文件或通过网络发送时,需要将它转换为一系列字节。这就是所谓的序列化。
Java内置了这种机制,其他选项包括XML或JSON。
需要进行序列化的示例:缓存对象、进行远程方法调用、将对象图保存到磁盘。
您还可以使用序列化实现对象克隆
序列化通常指将对象转换为一系列位。在Java中,它是一个必不可少的部分,因为Java主要用于基于Web的应用程序,即使要使数据在网络上可用。
当一个类需要将数据发送到另一个类时,如果这两个类位于不同的位置或硬盘上,就需要进行序列化。
反序列化是序列化的逆操作。
String类和所有包装类默认实现了Serializable接口。
Serializable接口也是一个标记接口,它为您的类提供了序列化的能力。因此,如果我们想要通过网络发送对象的状态,就应该实现Serializable接口。
public class Serializer {
public static void write(Object o, File f) throws IOException {
f.delete();
f.createNewFile();
FileOutputStream fileOut = new FileOutputStream(f);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(o);
out.close();
fileOut.close();
}
public static Object read(File f) throws Exception{
FileInputStream fileIn = new FileInputStream(f);
ObjectInputStream in = new ObjectInputStream(fileIn);
Object e = in.readObject();
in.close();
fileIn.close();
return e;
}
public static byte[] toBytes(Object o) {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(o);
out.flush();
bytes = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException ex) {
// ignore close exception
}
}
return bytes;
}
public static Object fromBytes(byte[] bytes) {
Object o = null;
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
o = in.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
// ignore close exception
}
}
return o;
}
}