O que é serialização de objeto?


Respostas:


400

Serialização é a conversão de um objeto em uma série de bytes, para que o objeto possa ser facilmente salvo em armazenamento persistente ou transmitido por um link de comunicação. O fluxo de bytes pode ser desserializado - convertido em uma réplica do objeto original.


16
isso é obrigatório? devo serializar dados antes de enviá-los? para qual formato ele é convertido?
Francisco Corrales Morales

15
@FranciscoCorralesMorales - Nos bastidores, todos os dados serão serializados antes de serem enviados por um fluxo. Quanto você precisa fazer, e em qual formato ele estará, depende de qual plataforma e bibliotecas você está usando.
TarkaDaal 31/07

3
@FranciscoCorralesMorales Como você está dizendo isso? Quero dizer que você está dizendo que o formato depende da plataforma e das bibliotecas. Eu realmente quero saber o formato.
JAVA

11
É aplicável apenas a objetos? Podemos serializar variáveis ​​(declaradas sem o uso de objetos)?
Rumado 31/03/19

Apenas Objetos @Rumado
anKotliner

395

Você pode pensar em serialização como o processo de converter uma instância de objeto em uma sequência de bytes (que pode ser binária ou não, dependendo da implementação).

É muito útil quando você deseja transmitir dados de um objeto pela rede, por exemplo, de uma JVM para outra.

Em Java, o mecanismo de serialização é incorporado à plataforma, mas você precisa implementar a interface Serializable para tornar um objeto serializável.

Você também pode impedir que alguns dados em seu objeto sejam serializados, marcando o atributo como transitório .

Finalmente, você pode substituir o mecanismo padrão e fornecer o seu próprio; isso pode ser adequado em alguns casos especiais. Para fazer isso, você usa um dos recursos ocultos no java .

É importante notar que o que é serializado é o "valor" do objeto, ou o conteúdo, e não a definição de classe. Assim, os métodos não são serializados.

Aqui está uma amostra muito básica com comentários para facilitar sua leitura:

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();
    }
}

Quando executamos este programa, o arquivo "o.ser" é criado e podemos ver o que aconteceu por trás.

Se alterarmos o valor de: someInteger para, por exemplo , Integer.MAX_VALUE , poderemos comparar a saída para ver qual é a diferença.

Aqui está uma captura de tela mostrando exatamente essa diferença:

texto alternativo

Você consegue identificar as diferenças? ;)

Há um campo relevante adicional na serialização Java: O serialversionUID, mas acho que isso já é muito longo para cobri-lo.


11
@ instância raam86 é o objeto que está sendo serializado. Você pode pensar no método main como um programa separado que cria um objeto do tipoSerializationSample
OscarRyz

2
@ raam86 é a primeira instrução no método principal: SerializationSample instance = new SerializationSample();a saída é criada e o objeto gravado nessa saída.
OscarRyz 03/10/12

11
Oh. Não seguimos perto o suficiente. Ótimo!!
raam86

11
@jacktrades Por que você não tenta. Basta copiar / colar o exemplo e veja "NotSerializableException" sendo jogado :)
OscarRyz

11
@ jacktrades porque o computador não foi informado de que o objeto pode ser serializado :) o que se entende por oos?
Chris Bennett

101

Ousar responder à pergunta de 6 anos de idade, adicionando apenas um entendimento de alto nível para pessoas novas em Java

O que é serialização?

Convertendo um objeto em bytes

O que é desserialização?

Convertendo bytes de volta em um objeto (Desserialização).

Quando a serialização é usada?

Quando queremos persistir o objeto. Quando queremos que o objeto exista além da vida útil da JVM.

Exemplo do mundo real:

ATM: Quando o titular da conta tenta sacar dinheiro do servidor por meio do caixa eletrônico, as informações do titular da conta, como detalhes da retirada, serão serializadas e enviadas ao servidor onde os detalhes são desserializados e usados ​​para executar operações.

Como a serialização é realizada em java.

  1. Implementar java.io.Serializableinterface (interface de marcador, portanto, não há método para implementar).

  2. Persistir no objeto: Use java.io.ObjectOutputStreamclass, um fluxo de filtro que é um invólucro em torno de um fluxo de bytes de nível inferior (para gravar Object em sistemas de arquivos ou transferir um objeto achatado através de uma conexão de rede e reconstruído do outro lado).

    • writeObject(<<instance>>) - para escrever um objeto
    • readObject() - ler um objeto serializado

Lembrar:

Quando você serializa um objeto, apenas o estado do objeto será salvo, não o arquivo de classe ou os métodos do objeto.

Ao serializar um objeto de 2 bytes, você vê um arquivo serializado de 51 bytes.

Etapas de como o objeto é serializado e desserializado.

Resposta para: Como ele se converteu em um arquivo de 51 bytes?

  • Primeiro, grava os dados mágicos do fluxo de serialização (STREAM_MAGIC = "AC ED" e STREAM_VERSION = versão da JVM).
  • Em seguida, ele grava os metadados da classe associada a uma instância (comprimento da classe, o nome da classe, serialVersionUID).
  • Em seguida, ele recursivamente grava os metadados da superclasse até encontrar java.lang.Object.
  • Em seguida, começa com os dados reais associados à instância.
  • Por fim, grava os dados dos objetos associados à instância, começando pelos metadados no conteúdo real.

Se você estiver interessado em informações mais detalhadas sobre serialização Java, consulte este link .

Edit : Mais um bom link para ler.

Isso responderá a algumas perguntas frequentes:

  1. Como não serializar nenhum campo na classe.
    Ans: use palavra-chave transitória

  2. Quando a classe filha é serializada, a classe pai é serializada?
    Resp: Não, se um pai não estiver estendendo o campo Pais da interface serializável, não será serializado.

  3. Quando um pai é serializado, a classe filho é serializada?
    Resp: Sim, por padrão, a classe filho também é serializada.

  4. Como evitar que a classe filho seja serializada?
    Resp: a. Substitua writeObject e readObject método e throw NotSerializableException.

    b. Além disso, você pode marcar todos os campos como transitórios na classe filho.

  5. Algumas classes no nível do sistema, como Thread, OutputStream e suas subclasses e Socket, não são serializáveis.

3
muito obrigado por esta resposta sucinta, foi muito útil!
Nobi

21

A serialização está pegando um objeto "ativo" na memória e convertendo-o em um formato que pode ser armazenado em algum lugar (por exemplo, na memória, no disco) e posteriormente "desserializado" novamente em um objeto ativo.


14

Gostei da forma como @OscarRyz apresenta. Embora aqui eu continue a história da serialização que foi originalmente escrita por @amitgupta.

Mesmo sabendo sobre a estrutura da classe do robô e tendo os dados serializados, o cientista da Terra não conseguiu desserializar os dados que podem fazer os robôs funcionarem.

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

Os cientistas de Mars estavam aguardando o pagamento completo. Depois que o pagamento foi feito, os cientistas de Marte compartilharam o UID serialversion com os cientistas da Terra. O cientista da Terra definiu a classe de robô e tudo ficou bem.


9

Serialização significa objetos persistentes em java. Se você deseja salvar o estado do objeto e deseja reconstruí-lo posteriormente (pode estar em outra JVM), a serialização pode ser usada.

Observe que as propriedades de um objeto serão salvas apenas. Se você deseja ressuscitar o objeto novamente, deve ter o arquivo de classe, porque apenas as variáveis ​​de membro serão armazenadas e não as funções de membro.

por exemplo:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

O Searializable é uma interface de marcador que marca que sua classe é serializável. A interface do marcador significa que é apenas uma interface vazia e o uso dessa interface notificará a JVM de que essa classe pode ser serializada.


9

Meus dois centavos do meu próprio blog:

Aqui está uma explicação detalhada da serialização : (meu próprio blog)

Serialização:

Serialização é o processo de persistir o estado de um objeto. É representado e armazenado na forma de uma sequência de bytes. Isso pode ser armazenado em um arquivo. O processo para ler o estado do objeto no arquivo e restaurá-lo é chamado desserialização.

Qual é a necessidade de serialização?

Na arquitetura moderna, sempre há a necessidade de armazenar o estado do objeto e depois recuperá-lo. Por exemplo, no Hibernate, para armazenar um objeto, devemos tornar a classe Serializable. O que ele faz é que, uma vez que o estado do objeto é salvo na forma de bytes, ele pode ser transferido para outro sistema que pode ler o estado e recuperar a classe. O estado do objeto pode vir de um banco de dados ou de uma jvm diferente ou de um componente separado. Com a ajuda da serialização, podemos recuperar o estado do objeto.

Código Exemplo e explicação:

Primeiro, vamos dar uma olhada na classe 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;
        }
}

No código acima, pode ser visto que a classe Item implementa Serializable .

Essa é a interface que permite que uma classe seja serializável.

Agora podemos ver uma variável chamada serialVersionUID é inicializada na variável Long. Esse número é calculado pelo compilador com base no estado da classe e nos atributos da classe. Este é o número que ajudará a jvm a identificar o estado de um objeto ao ler o estado do objeto no arquivo.

Para isso, podemos dar uma olhada na documentação oficial da Oracle:

O tempo de execução de serialização associa a cada classe serializável um número de versão, chamado serialVersionUID, usado durante a desserialização para verificar se o remetente e o destinatário de um objeto serializado carregaram classes para esse objeto que são compatíveis com a serialização. Se o receptor carregou uma classe para o objeto que possui um serialVersionUID diferente daquele da classe do remetente correspondente, a desserialização resultará em uma InvalidClassException. Uma classe serializável pode declarar seu próprio serialVersionUID explicitamente declarando um campo denominado "serialVersionUID" que deve ser estático, final e do tipo long: ANY-ACCESS-MODIFIER static final long serial serialVersionUID = 42L; Se uma classe serializável não declarar explicitamente um serialVersionUID, o tempo de execução da serialização calculará um valor serialVersionUID padrão para essa classe com base em vários aspectos da classe, conforme descrito na Especificação de serialização de objetos Java (TM). No entanto, é altamente recomendável que todas as classes serializáveis ​​declarem explicitamente os valores serialVersionUID, pois a computação serialVersionUID padrão é altamente sensível aos detalhes da classe que podem variar dependendo das implementações do compilador e, portanto, resultar em InvalidClassExceptions inesperadas durante a desserialização. Portanto, para garantir um valor consistente serialVersionUID em diferentes implementações do compilador java, uma classe serializável deve declarar um valor explícito serialVersionUID. Também é altamente recomendável que declarações explícitas serialVersionUID usem o modificador privado sempre que possível,

Se você notou que existe outra palavra-chave que é transitória .

Se um campo não for serializável, ele deve ser marcado como transitório. Aqui, marcamos o itemCostPrice como transitório e não queremos que ele seja gravado em um arquivo

Agora vamos dar uma olhada em como escrever o estado de um objeto no arquivo e depois ler a partir daí.

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();
        }
     }
}

No exemplo acima, podemos ver um exemplo de serialização e desserialização de um objeto.

Para isso, usamos duas classes. Para serializar o objeto, usamos ObjectOutputStream. Nós usamos o método writeObject para gravar o objeto no arquivo.

Para desserializar, usamos ObjectInputStream que lê o objeto no arquivo. Ele usa readObject para ler os dados do objeto no arquivo.

A saída do código acima seria como:

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]

Observe que itemCostPrice do objeto desserializado é nulo pois não foi gravado.

Já discutimos o básico sobre serialização de Java na parte I deste artigo.

Agora vamos discutir profundamente e como funciona.

Primeiro vamos começar com o serialversionuid.

O serialVersionUID é usado como um controle de versão em uma classe Serializable.

Se você não declarar explicitamente um serialVersionUID, a JVM fará isso para você automaticamente, com base em várias propriedades da classe Serializable.

Algoritmo de cálculo de serialversionuid de Java (Leia mais detalhes aqui)

  1. O nome da turma.
    1. Os modificadores de classe escritos como um número inteiro de 32 bits.
    2. O nome de cada interface classificada por nome.
    3. Para cada campo da classe classificado por nome do campo (exceto campos estáticos e transitórios privados: O nome do campo. Os modificadores do campo gravados como um número inteiro de 32 bits. O descritor do campo.
    4. Se existir um inicializador de classe, escreva o seguinte: O nome do método,.
    5. O modificador do método, java.lang.reflect.Modifier.STATIC, gravado como um número inteiro de 32 bits.
    6. O descritor do método, () V.
    7. Para cada construtor não particular classificado por nome e assinatura do método: O nome do método,. Os modificadores do método gravados como um número inteiro de 32 bits. O descritor do método.
    8. Para cada método não privado classificado por nome e assinatura do método: O nome do método. Os modificadores do método gravados como um número inteiro de 32 bits. O descritor do método.
    9. O algoritmo SHA-1 é executado no fluxo de bytes produzido pelo DataOutputStream e produz cinco valores de 32 bits sha [0..4]. O valor do hash é montado a partir dos primeiro e segundo valores de 32 bits do resumo da mensagem SHA-1. Se o resultado do resumo da mensagem, as cinco palavras de 32 bits H0 H1 H2 H3 H4, estiverem em uma matriz de cinco valores int denominados sha, o valor do hash será calculado da seguinte forma:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Algoritmo de serialização do Java

O algoritmo para serializar um objeto é descrito abaixo:
1. Ele grava os metadados da classe associada a uma instância.
2. Escreve recursivamente a descrição da superclasse até encontrar java.lang.object .
3. Depois de terminar de gravar as informações de metadados, ele começa com os dados reais associados à instância. Mas desta vez, começa na superclasse superior.
4. Grava recursivamente os dados associados à instância, iniciando da superclasse mínima para a classe mais derivada.

Coisas para manter em mente:

  1. Os campos estáticos em uma classe não podem ser serializados.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
  2. Se o serialversionuid for diferente na classe de leitura, será lançada uma InvalidClassExceptionexceção.

  3. Se uma classe implementar serializável, todas as suas subclasses também serão serializáveis.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
  4. Se uma classe tiver uma referência a outra classe, todas as referências deverão ser Serializáveis, caso contrário, o processo de serialização não será executado. Nesse caso, NotSerializableException é lançada em tempo de execução.

Por exemplo:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

11
'Serialização é o processo de serializar o estado de um objeto é representado e armazenado na forma de uma sequência de bytes' não faz sentido. Se o serialVersionUIDfor diferente, ele lançará um InvalidClassException, não um ClassCastException. Não é necessário desperdiçar todo esse espaço respeitando a serialVersionUIDcomputação. A documentação é citada, com tamanho excessivo, mas não está vinculada ou citada corretamente. Muita penugem aqui e muitos erros.
Marquês de Lorne

'Serialização é o processo de serialização' permanece sem sentido.
Marquês de Lorne

6

Serialização é o processo de converter o estado de um objeto em bits, para que ele possa ser armazenado em um disco rígido. Quando você desserializa o mesmo objeto, ele retém seu estado posteriormente. Permite recriar objetos sem precisar salvar as propriedades dos objetos manualmente.

http://en.wikipedia.org/wiki/Serialization


"... para que possa ser armazenado em um disco rígido." Ou transferido através de um protocolo binário.
Jim Anderson

4

Serialização de objetos Java

insira a descrição da imagem aqui

Serializationé um mecanismo para transformar um gráfico de objetos Java em uma matriz de bytes para armazenamento ( to disk file) ou transmissão ( across a network), usando desserialização , podemos restaurar o gráfico de objetos. Os gráficos dos objetos são restaurados corretamente usando um mecanismo de compartilhamento de referência. Porém, antes de armazenar, verifique se serialVersionUID do arquivo de entrada / rede e o arquivo .class serialVersionUID são iguais. Caso contrário, jogue a java.io.InvalidClassException.

Cada classe com versão deve identificar a versão original da classe para a qual é capaz de gravar fluxos e a partir da qual pode ler. Por exemplo, uma classe com versão deve declarar:

Sintaxe serialVersionUID

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID é essencial para o processo de serialização. Mas é opcional para o desenvolvedor adicioná-lo ao arquivo de origem java. Se um serialVersionUID não estiver incluído, o tempo de execução da serialização gerará um serialVersionUID e o associará à classe. O objeto serializado conterá esse serialVersionUID junto com outros dados.

Nota - É altamente recomendável que todas as classes serializáveis ​​declarem explicitamente um serialVersionUID e since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, portanto, podem resultar em conflitos inesperados de serialVersionUID durante a desserialização, causando falha na desserialização.

Inspecionando classes serializáveis

insira a descrição da imagem aqui


Um objeto Java é apenas serializável. se uma classe ou qualquer uma de suas superclasses implementa a interface java.io.Serializable ou sua subinterface, java.io.Externalizable .

  • Uma classe deve implementar a interface java.io.Serializable para serializar seu objeto com êxito. Serializable é uma interface de marcador e é usada para informar ao compilador que a classe que o implementa deve ser adicionada ao comportamento serializável. Aqui, a Java Virtual Machine (JVM) é responsável por sua serialização automática.

    transitória java.io.Serializable interface

    Ao serializar um objeto, se não queremos que certos membros de dados do objeto sejam serializados, podemos usar o modificador transitório. A palavra-chave transitória impedirá que esse membro de dados seja serializado.

    • Os campos declarados como transitórios ou estáticos são ignorados pelo processo de serialização.

    TRANSITÓRIO E VOLÁTIL

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
  • A implementação da interface Externalizável permite que o objeto assuma o controle completo sobre o conteúdo e o formato do formulário serializado do objeto. Os métodos da interface Externalizável, writeExternal e readExternal, são chamados para salvar e restaurar o estado dos objetos. Quando implementados por uma classe, eles podem escrever e ler seu próprio estado usando todos os métodos de ObjectOutput e ObjectInput. É de responsabilidade dos objetos lidar com qualquer versão que ocorra.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
  • Somente objetos que suportam a interface java.io.Serializable ou java.io.Externalizable podem ser written to/read from fluxos. A classe de cada objeto serializável é codificada, incluindo o nome e a assinatura da classe, os valores dos campos e matrizes do objeto e o fechamento de quaisquer outros objetos mencionados nos objetos iniciais.

Exemplo serializável para arquivos

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Exemplo serializável em rede

Distribuir o estado do objeto por diferentes espaços de endereço, em diferentes processos no mesmo computador ou até em vários computadores conectados via rede, mas que trabalham juntos compartilhando dados e chamando métodos.

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@Vejo


11
Quando você adiciona uma resposta a uma pergunta de seis anos que já possui várias respostas muito boas, você precisa fazer muito melhor do que uma cacofonia de erros de ortografia.
Marquês de Lorne

@ejp Downvoting é a ferramenta para expressar sua opinião negativa. Ser ofensivo e mal educado é inaceitável.
Konstantinos Chertouras

11
@KonstantinosChertouras Dar razões para o voto negativo é útil para o pôster, e essas são as minhas razões, gostando ou não da maneira que desejar.
Marquês de Lorne

Você também precisa evitar erros, como afirmar que a serialização tem um objetivo de segurança. Não faz.
Marquês de Lorne

@EJP Atualizei minha postagem, corrigi que a serialização não é para fins de segurança, mas é usada para transformar o estado de um objeto em qualquer armazenamento e recuperar o estado original de um objeto usando SUID por meio da desserialização do mecanismo. JVM to JVM
Yash 28/11

3

Serialização é o processo de salvar um objeto em uma mídia de armazenamento (como um arquivo ou um buffer de memória) ou transmiti-lo por uma conexão de rede em formato binário. Os objetos serializados são independentes da JVM e podem ser reinicializados por qualquer JVM. Nesse caso, o estado dos objetos java "na memória" é convertido em um fluxo de bytes. Este tipo de arquivo não pode ser entendido pelo usuário. É um tipo especial de objeto, ou seja, reutilizado pela JVM (Java Virtual Machine). Esse processo de serializar um objeto também é chamado de esvaziar ou organizar um objeto.

O objeto a ser serializado deve implementar a java.io.SerializableInterface. O mecanismo de serialização padrão para um objeto grava a classe do objeto, a assinatura da classe e os valores de todos os campos não transitórios e não estáticos.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutputinterface estende a DataOutputinterface e adiciona métodos para serializar objetos e gravar bytes no arquivo. A interface ObjectOutputStreamestende java.io.OutputStreame implementa ObjectOutput. Serializa objetos, matrizes e outros valores para um fluxo. Assim, o construtor de ObjectOutputStreamé escrito como:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

O código acima foi usado para criar a instância da ObjectOutputclasse com o ObjectOutputStream( )construtor que leva a instância doFileOuputStream como parâmetro.

A ObjectOutputinterface é usada implementando a ObjectOutputStreamclasse O ObjectOutputStreamé construído para serializar o objeto.

Desserializando um Objeto em Java

A operação oposta da serialização é chamada desserialização, ou seja, extrair os dados de uma série de bytes é conhecida como desserialização, que também é chamada de inflar ou remover a distribuição.

ObjectInputStreamestende java.io.InputStreame implementa a ObjectInput interface. Deserializa objetos, matrizes e outros valores de um fluxo de entrada. Assim, o construtor de ObjectInputStreamé escrito como:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

O código acima do programa cria a instância da ObjectInputStreamclasse para desserializar o arquivo que foi serializado pela ObjectInputStreamclasse. O código acima cria a instância usando a instância da FileInputStreamclasse que contém o objeto de arquivo especificado que deve ser desserializado porque o ObjectInputStream()construtor precisa do fluxo de entrada.



2

Retorne o arquivo como um objeto: 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);
        }
    }

Isso não responde às partes 'o que é' ou 'por favor, explique' da pergunta.
Marquês de Lorne

1

| * | Serializando uma classe: Convertendo um objeto em bytes e bytes em objeto (Desserialização).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

| => Serialização de objetos é um processo de conversão do estado de um objeto em vapor de bytes.

  • | -> Implemente quando desejar que o objeto exista além da vida útil da JVM.
  • | -> Objeto serializado pode ser armazenado no banco de dados.
  • Objetos serializáveis ​​não podem ser lidos e entendidos por seres humanos, para que possamos obter segurança.

| => Desserialização de objeto é o processo de obter o estado de um objeto e armazená-lo em um objeto (java.lang.Object).

  • | -> Antes de armazenar seu estado, ele verifica se serialVersionUID do arquivo de entrada / rede e o arquivo .class serialVersionUID são iguais.
    & nbsp & nbspSe não lançar java.io.InvalidClassException.

| => Um objeto Java é apenas serializável, se sua classe ou qualquer uma de suas superclasses

  • implementa a interface java.io.Serializable ou
  • sua subinterface, java.io.Externalizable.

| => Os campos estáticos em uma classe não podem ser serializados.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

| => Se você não deseja serializar uma variável de uma classe, use a palavra-chave transitória

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

| => Se uma classe implementar serializável, todas as suas subclasses também serão serializáveis.

| => Se uma classe tiver uma referência a outra classe, todas as referências deverão ser Serializáveis, caso contrário, o processo de serialização não será executado. Nesse caso,
NotSerializableException é lançada em tempo de execução.


0

Vou oferecer uma analogia para potencialmente ajudar a solidificar o objetivo / praticidade conceitual da serialização / desserialização de objetos .

Eu imagino serialização / desserialização de objetos no contexto de tentar mover um objeto através de um dreno de tempestade. O objeto é essencialmente "decomposto" ou serializado em versões mais modulares de si mesmo - nesse caso, uma série de bytes - a fim de ser efetivamente concedida a passagem por um meio. Em um sentido computacional, poderíamos ver o caminho percorrido pelos bytes através do dreno de tempestade como sendo semelhante aos bytes viajando através de uma rede. Estamos transmutando nosso objeto para nos adaptarmos a um modo de transporte ou formato mais desejável. O objeto serializado normalmente será armazenado em um arquivo binário que pode ser lido posteriormente, gravado ou ambos.

Talvez uma vez que nosso objeto seja capaz de passar pelo ralo como uma série de bytes decompostos, talvez desejemos armazenar essa representação do objeto como dados binários em um banco de dados ou unidade de disco rígido. O principal argumento, porém, é que, com serialização / desserialização, temos a opção de deixar nosso objeto permanecer em sua forma binária após ser serializado, ou "recuperar" a forma original do objeto executando a desserialização.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.