Serializable是什么意思?

Java在Java中是什么意思呢? 或者一般来说,对于这个问题…

串行化是将一个对象从内存持久化到一系列位,例如保存到磁盘上。 反序列化是相反的 – 从磁盘读取数据来保存/创build一个对象。

在你的问题的上下文中,它是一个接口,如果在一个类中实现的话,这个类可以被不同的序列化器自动序列化和反序列化。

这意味着类的实例可以转换为字节stream(例如,保存到文件),然后再转换回类。 这种重新加载可能发生在程序的不同实例中,甚至在不同的机器上。 但是,序列化(使用任何语言)都涉及到各种各样的问题,特别是当你引用可串行化的对象时。

虽然大部分的用户已经给出了答案,但是我想给那些需要它的人添加一个例子来解释这个想法:

假设你有一个如下的class级人员:

 public class Person implements java.io.Serializable { /** * */ private static final long serialVersionUID = 1L; public String firstName; public String lastName; public int age; public String address; public void play() { System.out.println(String.format( "If I win, send me the trophy to this address: %s", address)); } @Override public String toString() { return String.format(".....Person......\nFirst Name = %s\nLast Name = %s", firstName, lastName); } } 

然后你创build一个这样的对象:

 Person william = new Person(); william.firstName = "William"; william.lastName = "Kinaan"; william.age = 26; william.address = "Lisbon, Portugal"; 

您可以将该对象序列化为多个stream。 我会做到这两个stream:

序列化为标准输出:

 public static void serializeToStandardOutput(Person person) throws IOException { OutputStream outStream = System.out; ObjectOutputStream stdObjectOut = new ObjectOutputStream(outStream); stdObjectOut.writeObject(person); stdObjectOut.close(); outStream.close(); } 

序列化到一个文件:

 public static void serializeToFile(Person person) throws IOException { OutputStream outStream = new FileOutputStream("person.ser"); ObjectOutputStream fileObjectOut = new ObjectOutputStream(outStream); fileObjectOut.writeObject(person); fileObjectOut.close(); outStream.close(); } 

然后:

从文件反序列化:

 public static void deserializeFromFile() throws IOException, ClassNotFoundException { InputStream inStream = new FileInputStream("person.ser"); ObjectInputStream fileObjectIn = new ObjectInputStream(inStream); Person person = (Person) fileObjectIn.readObject(); System.out.println(person); fileObjectIn.close(); inStream.close(); } 

序列化涉及将对象的当前状态保存到stream中,并从该stream恢复对等对象。 stream作为对象的容器

可序列化被称为接口,但更像是编译器的标志。 它说这个对象可以保存。 除了没有可序列化对象和标志易失性的所有对象实例variables将被保存。

想象一下,你的应用程序可以改变颜色作为一个选项,而不需要保持外部设置,每次运行时都需要改变颜色。

序列化是一种将对象和数据存储或写入文件的技术。 通过使用ObjectOutputStreamFileOutputStream类。 这些类具有持久对象的特定方法。 像writeObject();

与数字清楚地解释。 看到这里了解更多信息

从另一个angular度来展示。 序列化是一种称为“标记接口”的接口。 标记接口是一个不包含方法声明的接口,而只是指定(或“标记”)实现接口的类作为一些属性。 如果你理解多态性,这将是非常有意义的。 在Serializable标记接口的情况下,如果ObjectOutputStream.write(Object)方法的参数没有实现接口,将会失败。 这在java中是一个潜在的错误,可能是ObjectOutputStream.write(Serializable)

强烈推荐:从Joshua Bloch的Effective Java中读取第37项以了解更多信息。

这里是序列化的详细解释 :(我自己的博客)

连载:

序列化是序列化对象状态的过程,以字节序列的forms表示和存储。 这可以存储在一个文件中。 从文件中读取对象的状态并恢复它的过程称为反序列化。

什么是序列化的需要?

在现代架构中,总是需要存储对象状态,然后检索它。 例如在Hibernate中,要存储一个对象,我们应该使类Serializable。 它的作用是,一旦对象状态以字节的forms保存,它可以被传送到另一个系统,然后可以从状态中读取和检索类。 对象状态可以来自数据库或不同的jvm,也可以来自不同的组件。 在序列化的帮助下,我们可以检索对象状态。

代码示例和说明:

首先让我们来看看Item类:

 public class Item implements Serializable{ /** * This is the Serializable class */ private static final long serialVersionUID = 475918891428093041L; private Long itemId; private String itemName; private transient Double itemCostPrice; public Item(Long itemId, String itemName, Double itemCostPrice) { super(); this.itemId = itemId; this.itemName = itemName; this.itemCostPrice = itemCostPrice; } public Long getItemId() { return itemId; } @Override public String toString() { return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]"; } public void setItemId(Long itemId) { this.itemId = itemId; } public String getItemName() { return itemName; } public void setItemName(String itemName) { this.itemName = itemName; } public Double getItemCostPrice() { return itemCostPrice; } public void setItemCostPrice(Double itemCostPrice) { this.itemCostPrice = itemCostPrice; } } 

在上面的代码中可以看出Item类实现了Serializable

这是使类可以被序列化的接口。

现在我们可以看到一个名为serialVersionUID的variables被初始化为Longvariables。 此编号由编译器根据类的状态和类属性进行计算。 这是帮助jvm在从文件读取对象状态时识别对象状态的数字。

为此,我们可以看看官方的Oracle文档:

序列化运行时与每个可序列化的类关联一个称为serialVersionUID的版本号,在反序列化过程中使用该版本号来validation序列化对象的发送者和接收者是否已经为该对象加载了与序列化兼容的类。 如果接收者已经为与对应的发送者类具有不同serialVersionUID的对象加载了类,则反序列化将导致InvalidClassExceptionexception。 一个可序列化的类可以通过声明一个名为“serialVersionUID”的字段声明自己的serialVersionUID,该字段必须是static,final和longtypes:ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 如果可序列化类没有显式声明serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认serialVersionUID值,如Java(TM)对象序列化规范中所述。 但是,强烈build议所有可序列化的类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类详细信息高度敏感,这些类可能因编译器实现而异,因此在反序列化期间可能会导致意外的InvalidClassException。 因此,为了保证在不同的java编译器实现中保持一致的serialVersionUID值,可序列化的类必须声明一个显式的serialVersionUID值。 还强烈build议显式serialVersionUID声明尽可能使用private修饰符,因为这样的声明仅适用于立即声明的类 – serialVersionUID字段作为inheritance成员是无用的。

如果你已经注意到有另一个关键字,我们已经使用,这是短暂的

如果某个字段不可序列化,则必须标记为瞬态。 在这里,我们将itemCostPrice标记为transient,并且不希望将其写入文件中

现在让我们来看看如何在文件中写入一个对象的状态,然后从那里读取它。

 public class SerializationExample { public static void main(String[] args){ serialize(); deserialize(); } public static void serialize(){ Item item = new Item(1L,"Pen", 12.55); System.out.println("Before Serialization" + item); FileOutputStream fileOut; try { fileOut = new FileOutputStream("/tmp/item.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(item); out.close(); fileOut.close(); System.out.println("Serialized data is saved in /tmp/item.ser"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void deserialize(){ Item item; try { FileInputStream fileIn = new FileInputStream("/tmp/item.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); item = (Item) in.readObject(); System.out.println("Serialized data is read from /tmp/item.ser"); System.out.println("After Deserialization" + item); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } 

在上面我们可以看到一个对象序列化和反序列化的例子。

为此,我们使用了两个类。 为了序列化我们使用ObjectOutputStream的对象。 我们使用writeObject方法在文件中写入对象。

对于反序列化,我们使用了从文件中读取对象的ObjectInputStream。 它使用readObject从文件读取对象数据。

上述代码的输出如下所示:

 Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55] Serialized data is saved in /tmp/item.ser After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null] 

请注意,来自反序列化对象的itemCostPrice空,因为它没有被写入。

只是添加到其他答案和一般性。 序列化有时被称为归档,例如在Objective-C中。

序列化:将对象的状态写入文件/networking或任何地方。 (平均Java对象支持窗体到文件支持窗体或networking支持窗体)

反序列化:从文件/networking或任何地方读取对象的状态。 (平均文件/networking支持的forms到Java对象支持的forms)