“对象序列化”是什么意思?你能举例解释一下吗?
当前回答
Serialization is the process of saving an object in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form. The serialized objects are JVM independent and can be re-serialized by any JVM. In this case the "in memory" java objects state are converted into a byte stream. This type of the file can not be understood by the user. It is a special types of object i.e. reused by the JVM (Java Virtual Machine). This process of serializing an object is also called deflating or marshalling an object.
要序列化的对象必须实现java.io.Serializable Interface。 对象的默认序列化机制写入对象的类、类签名以及所有非瞬态和非静态字段的值。
class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,
ObjectOutput接口扩展了DataOutput接口,并添加了用于序列化对象和向文件写入字节的方法。ObjectOutputStream扩展了java.io.OutputStream并实现了ObjectOutput接口。它将对象、数组和其他值序列化到流中。因此ObjectOutputStream的构造函数被写成:
ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));
上面的代码已用于使用ObjectOutputStream()构造函数创建ObjectOutput类的实例,该构造函数将FileOuputStream的实例作为参数。
ObjectOutput接口用于实现ObjectOutputStream类。构造ObjectOutputStream是为了序列化对象。
在java中反序列化对象
与序列化相反的操作称为反序列化,即从一系列字节中提取数据称为反序列化,也称为膨胀或解组。
ObjectInputStream扩展了java.io.InputStream,实现了ObjectInput接口。它反序列化来自输入流的对象、数组和其他值。因此ObjectInputStream的构造函数被写成:
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));
上面的程序代码创建了ObjectInputStream类的实例,以反序列化已被ObjectInputStream类序列化的文件。上面的代码使用FileInputStream类的实例创建实例,FileInputStream类包含必须反序列化的指定文件对象,因为ObjectInputStream()构造函数需要输入流。
其他回答
序列化是将Java对象转换为字节数组,然后再将其转换为保留状态的对象的过程。适用于通过网络发送对象或将内容缓存到磁盘等各种事情。
请阅读这篇简短的文章,它很好地解释了编程过程的一部分,然后转到Serializable javadoc。你也可能对这个相关的问题感兴趣。
您可以将序列化看作是将对象实例转换为字节序列的过程(根据实现的不同,字节序列可能是二进制的,也可能不是)。
当您希望通过网络传输一个对象数据时(例如从一个JVM传输到另一个JVM),它非常有用。
在Java中,序列化机制内置于平台中,但您需要实现Serializable接口以使对象可序列化。
还可以通过将属性标记为transient来防止对象中的某些数据被序列化。
最后,您可以覆盖默认机制,并提供您自己的;这可能适用于某些特殊情况。为此,您需要使用java中的一个隐藏特性。
重要的是要注意,被序列化的是对象的“值”或内容,而不是类定义。因此方法不是序列化的。
下面是一个非常基本的示例,带有注释,以方便阅读:
import java.io.*;
import java.util.*;
// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {
// These attributes conform the "value" of the object.
// These two will be serialized;
private String aString = "The value of that string";
private int someInteger = 0;
// But this won't since it is marked as transient.
private transient List<File> unInterestingLongLongList;
// Main method to test.
public static void main( String [] args ) throws IOException {
// Create a sample object, that contains the default values.
SerializationSample instance = new SerializationSample();
// The "ObjectOutputStream" class has the default
// definition to serialize an object.
ObjectOutputStream oos = new ObjectOutputStream(
// By using "FileOutputStream" we will
// Write it to a File in the file system
// It could have been a Socket to another
// machine, a database, an in memory array, etc.
new FileOutputStream(new File("o.ser")));
// do the magic
oos.writeObject( instance );
// close the writing.
oos.close();
}
}
当我们运行这个程序时,文件“o.ser”被创建,我们可以看到后面发生了什么。
如果我们将:someInteger的值更改为,例如Integer。MAX_VALUE,我们可以比较输出,看看有什么不同。
下面的截图正好显示了这种差异:
你能看出区别吗?;)
在Java序列化中还有一个额外的相关字段:serialversionUID,但我想这已经太长了,无法涵盖它。
序列化意味着在java中持久化对象。如果您希望保存对象的状态,并希望稍后重新构建该状态(可能在另一个JVM中),则可以使用序列化。
注意,对象的属性只会被保存。如果你想再次恢复对象,你应该有类文件,因为只存储成员变量而不存储成员函数。
eg:
ObjectInputStream oos = new ObjectInputStream(
new FileInputStream( new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();
serializable是一个标记接口,用来标记你的类是可序列化的。标记接口意味着它只是一个空接口,使用该接口将通知JVM该类可以被序列化。
将文件返回为Object: http://www.tutorialspoint.com/java/java_serialization.htm
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
序列化是将对象转换为一系列字节,以便可以轻松地将对象保存到持久存储器或通过通信链路进行流式传输。然后可以反序列化字节流,将其转换为原始对象的副本。
推荐文章
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- Java生成两个给定值之间的随机数
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 比较JUnit断言中的数组,简洁的内置方式?
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令