ClasseMB implements Serializable: por que?

Olá pessoal, tenho uma dúvida básica para tirar com vcs: É recomendado, nas minhas classes eu implementar o Serializable?? e Por que? e em quais classes eu devo fazer isso??

Valeu!!

Depende. A serialização é o ato de armazenar ou transferir um objeto. Por exemplo, transferir um objeto via Socket ou via RMI ou gravar um objeto em um arquivo.

Se esse for o caso, você deve implementar Serializable. Caso contrário, não há necessidade.

PS: Se esqueci de citar alguma ocasião em que serialização é usada, por favor complementem.

só nao esqueça, que se houver um atributo que vc queira serializar, mas q ele na verdade é uma referencia a um objeto de outra classe, vc deverá implementar serializable nela também, ou marcar o atributo como transient.

ALguem poderia me dar um exemplo mais prático? ainda estou com a dúvida!! :smiley:

Agradeço.

Suponha que você tenha uma classe Livro que faz parte de um sistema de biblioteca. Essa classe implementa Serializable, uma vez que seus objetos serão escritos em um arquivo:

import java.io.Serializable;

public class Livro implements Serializable {

	private static final long serialVersionUID = -5930904419691645745L;

	private String titulo;
	private String autor;
	private int numeroPaginas;
	private transient boolean emprestado;

	@Override
	public String toString() {
		return titulo + ", " + autor + " - " + numeroPaginas
				+ " páginas\nEmprestado: " + (emprestado ? "sim" : "não");
	}

	// getters e setters omitidos

}

E uma classe de teste para exemplificar tudo isso:

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Serializacao {

	public static void main(String[] args) {
		Livro livroOriginal = criaLivroDeExemplo();
		// vamos mostrar as informações do livro
		System.out.println("Livro antes de serializar:");
		System.out.println(livroOriginal);
		// serializando via ObjectStream:
		escreveLivro(livroOriginal);
		// serializando via XML:
		escreveLivroXML(livroOriginal);
		// vamos ler e mostrar os livros serializados:
		System.out.println("Livro serializado com ObjectStream:");
		System.out.println(leLivro());
		System.out.println("Livro serializado com XML:");
		System.out.println(leLivroXML());
	}

	static Livro criaLivroDeExemplo() {
		Livro livro = new Livro();
		livro.setAutor("João da Silva");
		livro.setTitulo("A volta dos que não foram");
		livro.setNumeroPaginas(218);
		livro.setEmprestado(true);
		return livro;
	}

	/**
	 * Usa ObjectOutputStream para escrever o objeto no arquivo.
	 * 
	 * @param livro
	 *            o livro a ser escrito
	 */
	static void escreveLivro(Livro livro) {
		ObjectOutputStream out = null;
		try {
			out = new ObjectOutputStream(new FileOutputStream("livro.dat"));
			// escrevemos o objeto
			out.writeObject(livro);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
				}
			}
		}
	}

	/**
	 * Lê um objeto do arquivo via ObjectInputStream.
	 * 
	 * @return o livro lido, ou null se houver algum erro.
	 */
	static Livro leLivro() {
		ObjectInputStream in = null;
		try {
			in = new ObjectInputStream(new FileInputStream("livro.dat"));
			// lemos o objeto
			return (Livro) in.readObject();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}
	}

	/**
	 * Usa XMLEncoder para escrever o objeto no arquivo.
	 * 
	 * @param livro
	 *            o livro a ser escrito
	 */
	static void escreveLivroXML(Livro livro) {
		XMLEncoder out = null;
		try {
			out = new XMLEncoder(new FileOutputStream("livro.xml"));
			// escrevemos o objeto
			out.writeObject(livro);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

	/**
	 * Lê um objeto do arquivo via XMLDecoder.
	 * 
	 * @return o livro lido, ou null se houver algum erro.
	 */
	static Livro leLivroXML() {
		XMLDecoder in = null;
		try {
			in = new XMLDecoder(new FileInputStream("livro.xml"));
			// lemos o objeto
			return (Livro) in.readObject();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (in != null) {
				in.close();
			}
		}
	}

}

Se você executar isso, perceberá que dois arquivos diferentes foram criados. Um binário (.dat, escrito com ObjectOutputStream) e um texto (.xml, escrito com XMLEncoder). Ambos tem a mesma função: transformar o objeto em um arquivo. Porém algumas peculiaridades:

  1. XMLEncoder cria um arquivo de texto puro, ObjectOutputStream não. Isso implica que os arquivos XML tendem a ser bem maiores que os arquivos binários.
  2. Mais uma consequência do item 1 é que o XML pode ser facilmente alterado por qualquer usuário. O arquivo binário, em contrapartida, não.
  3. O ObjectOutputStream honra o modificador transient, não serializando os atributos marcados com esse modificador. Já o XMLEncoder ignora esse atributo. Por isso o objetos do tipo Livro que foram lidos são diferentes nesse exemplo.

Note que, nesse caso, escrevemos o objeto em um arquivo. Poderíamos ter usado a serialização para enviar esse objeto via Socket ou até mesmo via RMI.

1 curtida