JavaRush /Blogue Java /Random-PT /Como funciona a serialização em Java
ramhead
Nível 13

Como funciona a serialização em Java

Publicado no grupo Random-PT
Neste artigo, explicaremos o que é serialização e como funciona em Java. Como funciona a serialização em Java - 1

Introdução

A serialização de objetos é a capacidade de um objeto armazenar uma cópia completa de si mesmo e de quaisquer outros objetos aos quais ele faz referência usando um fluxo de saída (por exemplo, para um arquivo externo). Dessa forma, o objeto pode ser recriado a partir da cópia serializada (salva) um pouco mais tarde, quando necessário. A serialização de objetos, um novo recurso introduzido no JDK 1.1, fornece uma função para converter grupos ou objetos individuais, em um fluxo de bits ou matriz de bytes, para armazenamento ou transmissão em uma rede. E como afirmado, um determinado fluxo de bits ou matriz de bytes pode ser convertido novamente em objetos Java. Isso acontece principalmente automaticamente graças às classes ObjectInputStreame ObjectOutputStream. O programador pode decidir implementar esta funcionalidade implementando a interface Serializableao criar a classe. O processo de serialização também é conhecido como empacotamento de objetos , enquanto a desserialização é conhecida como desempacotamento . A serialização é um mecanismo que permite que um objeto salve uma cópia de si mesmo e de todos os outros objetos referenciados por esse objeto em um arquivo externo usando a extensão ObjectOutputStream. Os objetos salvos podem ser estruturas de dados, diagramas, objetos de classe JFrameou quaisquer outros objetos, independentemente do seu tipo. Ao mesmo tempo, a serialização armazena informações sobre o tipo de objeto para que mais tarde, quando desserializado, essas informações sejam usadas para recriar o tipo exato de objeto que era. Portanto, a serialização fornece os seguintes recursos:
  • Um sistema para armazenar objetos, ou seja: salvar suas propriedades em um arquivo externo, em disco ou em um banco de dados.
  • Sistema de chamada de procedimento remoto.
  • Um sistema de distribuição de objetos, por exemplo, em componentes de software como COM, COBRA.
  • Sistema para identificar alterações em dados variáveis ​​ao longo do tempo.
Para compreender completamente o conceito de serialização, você precisa ter uma compreensão clara dos outros dois conceitos: persistência de objeto e persistência de thread. Aqui falaremos um pouco sobre cada um deles para relembrar. Uma explicação completa deles exigiria um capítulo separado para cada um desses conceitos.

Fluxos:

Todo programa deve gravar seus dados em um local de armazenamento ou canal, e todo programa deve ler dados de um canal ou local de armazenamento. Em Java, esses canais onde os programas gravam e dos quais os programas leem dados são chamados de Streams( Stream) . Como funciona a serialização em Java - 2
Figura 1. Representação gráfica de Threads
Os fluxos são divididos principalmente em dois tipos:
  • Classes de fluxo de bytes chamadas *Streams
  • Classes de fluxo de caracteres chamadas *Reader e *Writer
Cada fluxo de gravação de dados contém um conjunto de métodos de gravação. E cada thread de leitura de dados, respectivamente, possui um conjunto semelhante de métodos de leitura. Depois que o thread for criado, todos esses métodos deverão ser chamados.

Persistência

A persistência do objeto é a capacidade de um objeto sobreviver ou, em outras palavras, “sobreviver” à execução de um programa. Isso significa que qualquer objeto criado em tempo de execução será destruído pelo limpador JVM sempre que esse objeto não for mais usado. Mas se a API de persistência for implementada, esses objetos não serão destruídos pelo scavenger JVM, em vez disso poderão “viver”, o que também possibilita acessá-los na próxima vez que a aplicação for iniciada. Em outras palavras, persistência significa que existe um tempo de vida para um objeto, independente do tempo de vida da aplicação que está sendo executada. Uma maneira de implementar a persistência é armazenar objetos em algum lugar de um arquivo ou banco de dados externo e, em seguida, restaurá-los posteriormente usando esses arquivos ou o banco de dados como fontes. É aqui que a serialização entra em jogo. Qualquer objeto não persistente existe enquanto a JVM estiver em execução. Objetos serializados são simplesmente objetos convertidos em fluxos, que são então salvos em um arquivo externo ou transferidos por uma rede para armazenamento e recuperação.

Implementação da interface serializável

Qualquer classe deve implementar uma interface java.io.Serializablepara serializar objetos dessa classe. A interface Serializablenão possui métodos e apenas marca a classe para que ela possa ser identificada como serializável. Somente os campos de um objeto de classe serializado podem ser salvos. Métodos ou construtores não são armazenados como parte do fluxo serializado. Se algum objeto atuar como referência para outro objeto, os campos desse objeto também serão serializados se a classe desse objeto implementar a interface Serializable. Em outras palavras, o gráfico deste objeto assim obtido é totalmente serializável. Um gráfico de objeto inclui uma árvore ou estrutura de campos de um objeto e seus subobjetos. Duas classes principais que ajudam a implementar a interface Seriliazable:
  • ObjectInputStream
  • ObjectOutputStream
Listagem 1. Exemplo de classe simples para mostrar serialização
import java.io.*;
public class RandomClass implements Serializable {
 // Генерация рандомного значения
 private static int r() {
        return (int)(Math.random() * 10);
 }
    private int data[];
    // Конструктор
public RandomClass() {
        datafile = new int[r()];
        for (int i=0; i<datafile.length; i++)
        datafile[i]=r();
 }
    public void printout() {
 System.out.println("This RandomClass has "+datafile.length+" random integers");
 for (int i=0; i<datafile.length; i++) {
        System.out.print(datafile[i]+":");
        System.out.println();
    }
}
No código acima, é criada uma classe que é serializável porque "marcado" pela interface de serialização. A classe cria uma matriz de inteiros aleatórios quando uma instância dela é criada. O código abaixo mostra a capacidade de gravar objetos em um fluxo usando o ObjectOutputStream. O programa possui um array de números inteiros, mas para serialização não precisamos iterar sobre seus objetos internos. A interface Seriliazablecuida disso automaticamente. Listagem 2. Um exemplo simples de serialização de objetos para saída em um arquivo
import java.io.*;
import java.util.*;
public class OutSerialize {
    public static void main (String args[]) throws IOException {
        RandomClass rc1 = new RandomClass();
        RandomClass rc2 = new RandomClass();
//создание цепи потоков с потоком вывода an object в конце
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objects.dat"));
        Date now = new Date(System.currentTimeMillis());
//java.util.* был импортирован для использования класса Date
        out.writeObject(now);
        out.writeObject(rc1);
        out.writeObject(rc2);
out.close();
        System.out.println("I have written:");
System.out.println("A Date object: "+now);
        System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
 }
}
O código abaixo demonstra os recursos da classe ObjectInputStream, que lê dados serializados de um arquivo externo para um programa. Observe que os objetos são lidos na mesma ordem em que foram gravados no arquivo. Listagem 3. Lendo objetos serializados ou desserializando
import java.io.*;
import java.util.*;
public class InSerialize {
 public static void main (String args[]) throws  IOException, ClassNotFoundException {
    ObjectInputStream in =  new ObjectInputStream (new FileInputStream("objects.dat"));
 Date d1 = (Date)in.readObject();
 RandomClass rc1 = (RandomClass)in.readObject();
    RandomClass rc2 = (RandomClass)in.readObject();
    System.out.println("I have read:");
    System.out.println("A Date object: "+d1);
    System.out.println("Two Group of randoms");
    rc1.printout();
rc2.printout();
 }
}
Quase todas as classes Java podem ser serializadas, incluindo classes AWT. Um quadro, que é uma janela, contém um conjunto de componentes gráficos. Se o quadro for serializado, o mecanismo de serialização cuida disso e serializa todos os seus componentes e dados (posição, conteúdo, etc.). Alguns objetos de classe Java não podem ser serializados porque contêm dados que fazem referência a recursos efêmeros do sistema operacional. Por exemplo classes java.io.FileInputStreame java.lang.Thread. Se um objeto contiver referências a elementos não serializáveis, toda a operação de serialização falhará e uma exceção será lançada NotSerializableException. Se algum objeto se referir a uma referência de um objeto não serializado, ele poderá ser serializado usando a palavra-chave transitória . Listagem 4. Criando objetos serializáveis ​​usando a palavra-chave transitória
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
    private String studentID;
    private int sum;
}

Segurança na serialização

Serializar uma classe em Java envolve passar todos os seus dados para um arquivo externo ou banco de dados por meio de um fluxo. Podemos limitar os dados que serão serializados sempre que desejarmos. Existem duas maneiras de fazer isso:
  • Cada parâmetro de classe declarado como transitório não é serializado (por padrão, todos os parâmetros de classe são serializados)
  • Ou cada parâmetro da classe que queremos serializar é marcado com uma tag Externalizable(por padrão, nenhum parâmetro é serializado).
Um campo de dados não será serializado com ObjectOutputStream, quando chamado em um objeto, se o campo de dados desse objeto estiver marcado como transitório . Por exemplo: private transient String password. Por outro lado, para declarar explicitamente os dados de um objeto como serializáveis, devemos marcar a classe como gravando e lendo ExternalizablewriteExternalexplicitamente readExteranlos dados desse objeto.

Conclusão

O recurso de serialização de objetos é usado em muitos sistemas distribuídos como forma de transferir dados. Mas a serialização revela detalhes ocultos, destruindo assim a autenticidade dos tipos de dados abstratos, o que por sua vez destrói o encapsulamento. Ao mesmo tempo, é bom saber que os dados do objeto serializado são os mesmos dados que estavam no objeto original. Esta também é uma ótima oportunidade para implementar uma interface ObjectInputValidatione substituir um método validateObject(), mesmo se várias linhas de código forem usadas. Se o objeto não for encontrado, podemos lançar uma exceção apropriadamente InvalidObjectException. Artigo original: Como funciona a serialização em Java
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION