Pergunta

Eclipse emite avisos quando um serialVersionUID está faltando.

A classe serializável Foo não declarar uma final estática campo serialVersionUID do tipo long

O que é serialVersionUID e por que é importante? Por favor, mostre um exemplo onde serialVersionUID faltando irá causar um problema.

Foi útil?

Solução

Os docs para java.io.Serializable são provavelmente cerca de uma explicação tão boa quanto você vai ter:

Os associados serialização de tempo de execução, com cada classe seriável um número de versão, chamado um serialVersionUID, que é utilizado durante deserialização para verificar que o remetente e o receptor de um objecto em série têm classes carregadas para esse objecto que são compatíveis com respeito a serialização. Se o receptor tiver sido carregado uma classe para o objecto que tem um serialVersionUID diferente do que a classe do remetente correspondente, em seguida, deserialização irá resultar numa InvalidClassException . Uma classe serializável pode declarar a sua própria serialVersionUID explicitamente declarando um campo chamado serialVersionUID que deve ser estático, final, e do tipo long:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

Se uma classe serializável não declarar explicitamente um serialVersionUID, em seguida, o tempo de execução serialização irá calcular um valor serialVersionUID padrão para essa classe com base em vários aspectos da classe, conforme descrito no objeto Java (TM) serialização Specification. No entanto, é altamente recomendável que todas as classes serializáveis ??declarar explicitamente valores serialVersionUID, desde o computação serialVersionUID padrão é altamente sensível aos detalhes de classe que podem variar dependendo implementações do compilador, e pode, portanto, resultar em InvalidClassExceptions inesperada durante a desserialização . Portanto, para garantir um valor serialVersionUID consistente em diferentes implementações do compilador Java, uma classe serializável deve declarar um valor serialVersionUID explícito. É também aconselhado fortemente que as declarações serialVersionUID explícitas usar o modificador privado, sempre que possível, uma vez que tais declarações se aplicam apenas às imediatamente declarando campos classe serialVersionUID não são úteis como membros herdados.

Outras dicas

Se você está serialização só porque você tem que serialize para o bem da implementação (quem se importa se você serializar para um HTTPSession, por exemplo ... se ele é armazenado ou não, você provavelmente não se preocupam com de-serializing um objeto de formulário ), então você pode ignorar isso.

Se você está realmente usando a serialização, só importa se você planeja armazenar e recuperar objetos usando serialização diretamente. O serialVersionUID representa a sua versão classe, e você deve incrementá-lo se a versão atual de sua classe não é compatível com a sua versão anterior.

Na maioria das vezes, você provavelmente não vai usar a serialização diretamente. Se este for o caso, gerar um SerialVersionUID padrão clicando na opção rápida correção e não se preocupe com isso.

Eu não posso deixar passar esta oportunidade de ligar livro de Josh Bloch Effective Java (2nd Edition). O Capítulo 11 é um recurso indispensável na serialização Java.

Por Josh, o UID gerada automaticamente é gerado com base em um nome de classe, interfaces implementadas, e todo o público e membros protegidos. A alteração de qualquer destes em qualquer maneira vai mudar a serialVersionUID. Então você não precisa mexer com eles somente se tiver certeza de que há mais de uma versão da classe nunca vai ser serializado (seja através de processos ou recuperados do armazenamento em um momento posterior).

Se você ignorá-los para agora, e descobrir mais tarde que você precisa mudar a classe de alguma forma, mas manter a compatibilidade w / versão antiga da classe, você pode usar a ferramenta JDK serialver para gerar o serialVersionUID no velho classe e definir explicitamente que a nova classe. (Dependendo de suas mudanças pode ser necessário implementar também serialização personalizada adicionando métodos writeObject e readObject -. Ver javadoc Serializable ou capítulo acima mencionado 11)

Você pode dizer Eclipse para ignorar esses avisos serialVersionUID:

Janela> Preferências> Java> Compiler> Erros / Avisos> problemas de programação Potencial

No caso de você não sabia, há um monte de outros avisos que você pode ativar nesta seção (ou mesmo ter algum relatados como erros), muitos são muito úteis:

  • problemas de programação potenciais: Possível acidental boolean atribuição
  • problemas de programação potenciais: o acesso de ponteiro nulo
  • código desnecessário: variável local nunca é lido
  • código desnecessário: verificação nulo Redundante
  • código desnecessário: elenco desnecessários ou 'instanceof'

e muitos mais.

facilita serialVersionUID versionamento de dados serializados. Seu valor é armazenado com os dados quando a serialização. Quando de-serialização, a mesma versão é verificado para ver como os dados serializados corresponde ao código atual.

Se você quiser a versão seus dados, você normalmente começam com um serialVersionUID de 0, e bater-lo com cada mudança estrutural para a sua classe, que altera os dados serializados (adicionando ou removendo campos não-transitórios).

A built-in de-serialização mecanismo (in.defaultReadObject()) se recusam a de-serialize de versões antigas dos dados. Mas se você quiser, você pode definir o seu próprio readObject () -função que pode ler dados antigos. Este código personalizado pode então verificar o serialVersionUID a fim de saber qual versão os dados estão em e decidir como a de-serialize-la. Esta técnica de versão é útil se você armazenar serializado dados que sobrevive várias versões do seu código.

Mas o armazenamento de dados serializados para tal um longo período de tempo não é muito comum. É muito mais comum usar o mecanismo de serialização de dados temporariamente gravação para, por exemplo, um cache ou enviá-lo através da rede para outro programa com a mesma versão das partes relevantes da base de código.

Neste caso, você não está interessado em manter a compatibilidade com versões anteriores. Você só estão preocupados com a certeza de que as bases de código que estão se comunicando realmente tem as mesmas versões de classes relevantes. Para facilitar essa verificação uma, você deve manter a serialVersionUID como antes e não se esqueça de atualizá-lo ao fazer alterações em suas classes.

Se você se esqueça de atualizar o campo, você pode acabar com duas versões diferentes de uma classe com estrutura diferente, mas com a mesma serialVersionUID. Se isso acontecer, o mecanismo padrão (in.defaultReadObject()) não vai detectar qualquer diferença, e tentar de-serialize dados incompatíveis. Agora você pode acabar com um erro de execução críptico ou falha silenciosa (campos nulos). Estes tipos de erros podem ser difíceis de encontrar.

Assim, para ajudar este usecase, a plataforma Java oferece uma escolha de não definir o serialVersionUID manualmente. Em vez disso, um hash da classe estrutura irá ser gerado em tempo de compilação e utilizado como ID. Este mecanismo irá certificar-se que você nunca tem estruturas de classe diferentes com o mesmo id, e assim você não terá essas falhas de execução de serialização de difícil traço mencionado acima.

Mas há uma parte traseira para a estratégia id gerado automaticamente. Ou seja, que as identificações geradas para a mesma classe podem diferir entre compiladores (como indicado por Jon Skeet acima). Então, se você se comunica dados serializados entre o código compilado com diferentes compiladores, é recomendado para manter os ids manualmente qualquer maneira.

E se você é compatível com os seus dados, como no primeiro caso de uso mencionado, provavelmente você também quiser manter a ID de si mesmo. Isto a fim de obter ids legíveis e ter maior controle sobre quando e como eles mudam.

O que é um serialVersionUID e por que devo usá-lo?

SerialVersionUID é um identificador único para cada classe, JVM utiliza para comparar as versões da classe que assegurem que a mesma classe foi utilizado durante a serialização é carregado durante Desserialização.

Especificando um dá mais controle, embora JVM gera um, se você não especificar. O valor gerado pode diferir entre diferentes compiladores. Além disso, às vezes você quer apenas por algum motivo para proibir desserialização de objetos serializados velhos [backward incompatibility], e neste caso você só tem que mudar o serialVersionUID.

O javadocs para Serializable digamos :

o cálculo serialVersionUID padrão é altamente sensível à classe detalhes que podem variar de acordo com implementações do compilador, e pode portanto, resultar em InvalidClassExceptions inesperados durante desserialização.

Portanto, você deve declarar serialVersionUID porque nos dão mais controle .

Este artigo tem alguns pontos bons sobre o tema.

pergunta original pediu 'por que é importante' e 'exemplo', onde este Serial Version ID seria útil. Bem, eu encontrei um.

Say você cria uma classe Car, instanciá-lo e escrevê-lo para um fluxo de objeto. O objeto carro achatado senta no sistema de arquivos por algum tempo. Enquanto isso, se a classe Car é modificado pela adição de um novo campo. Mais tarde, quando você tenta ler (ou seja deserialize) o objeto Car achatada, você começa a java.io.InvalidClassException - porque todas as classes serializáveis ??são automaticamente dado um identificador único. Essa exceção é lançada quando o identificador da classe não é igual ao identificador do objeto achatado. Se você realmente pensa sobre isso, a exceção é lançada por causa da adição do novo campo. Você pode evitar essa exceção sendo lançada, controlando a si mesmo versionamento, declarando um serialVersionUID explícito. Há também uma pequena vantagem de desempenho em declarar explicitamente seu serialVersionUID (porque não tem que ser calculado). Então, é melhor prática para adicionar seu próprio serialVersionUID para suas classes serializáveis ??assim que criá-los como mostrado abaixo:

public class Car {
    static final long serialVersionUID = 1L; //assign a long value
}

Se você nunca precisará serializar seus objetos a matriz de bytes e enviar / armazená-los, então você não precisa se preocupar com isso. Se o fizer, então você deve considerar o seu serialVersionUID desde o desserializador do objeto irá combiná-lo com a versão do objeto seu carregador de classe tem. Leia mais sobre o assunto na especificação de linguagem Java.

Se você receber este aviso em uma classe que você não nunca pensar sobre a serialização, e que você não declarar-se implements Serializable, muitas vezes é porque você herdou de uma superclasse, que implementa Serializable. Muitas vezes, então seria melhor para delegar a um tal objeto, em vez de usar a herança.

Assim, em vez de

public class MyExample extends ArrayList<String> {

    public MyExample() {
        super();
    }
    ...
}

fazer

public class MyExample {
    private List<String> myList;

    public MyExample() {
         this.myList = new ArrayList<String>();
    }
    ...
}

e na myList.foo() métodos convite relevante em vez de this.foo() (ou super.foo()). (Isso não se encaixa em todos os casos, mas ainda com bastante frequência.)

Muitas vezes vejo pessoas que se estendem JFrame ou tal, quando eles realmente só precisa delegar a isso. (Isso também ajuda para a auto-completar em uma IDE, desde JFrame tem centenas de métodos, que você não precisa quando você quiser chamar seus entes personalizados em sua classe.)

Um caso em que o aviso (ou o serialVersionUID) é inevitável é quando você se estendem desde AbstractAction, normalmente em uma classe anônima, acrescentando apenas o método actionPerformed. Eu acho que não deve haver um aviso neste caso (desde que você normalmente pode serializar não confiável e anular tais classes anônimas de qualquer maneira accross diferentes versões de sua classe), mas não tenho certeza de como o compilador poderia reconhecer isso.

Para entender o significado de serialVersionUID campo, deve-se entender como serialização / desserialização funciona.

Quando um objeto de classe Serializable é serializado Java Runtime associa uma versão de série no. (Chamado como serialVersionUID) com este objeto serializado. No momento em que você desserializar este objeto serializado Java Runtime corresponde ao serialVersionUID do objeto serializado com o serialVersionUID da classe. Se ambos são iguais, então só ele prossegue com o novo processo de desserialização pessoa joga InvalidClassException.

Assim, podemos concluir que para tornar o processo de serialização / desserialização sucesso o serialVersionUID de objeto serializado deve ser equivalente ao serialVersionUID da classe. No caso, se o programador especifica o valor de serialVersionUID explicitamente no programa, em seguida, o mesmo valor será associado com o objeto serializado e da classe, independentemente da plataforma de serialização e deserialzation (por ex. Serialização pode ser feito em plataforma como o Windows usando o sol ou MS JVM e Deserialization pode estar em diferentes plataforma Linux usando Zing JVM).

Mas no caso, se serialVersionUID não é especificado pelo programador, em seguida, ao fazer a serialização \ desserialização de qualquer objeto, Java runtime usa seu próprio algoritmo para calculá-lo. Este algoritmo de cálculo serialVersionUID varia de um JRE para outro. Também é possível que o ambiente onde o objeto é serializado está usando um JRE (ex: SUN JVM) e o ambiente onde deserialzation acontece está usando Linux Jvm (Xing). Em tais casos serialVersionUID associado com objeto serializados será diferente do que o serialVersionUID de classe calculado no ambiente deserialzation. Por sua vez desserialização não será bem sucedido. Assim, para evitar tais situações / problemas programador sempre deve especificar serialVersionUID de classe Serializable.

Primeiro eu preciso explicar a serialização.
serialização permite converter o objeto para stream, para enviar esse objeto através da rede ou salvar em arquivo ou salvar em DB para uso carta.

Existem algumas regras para serialização .

  • Um objeto é serializável somente se sua classe ou de seus implementos superclasse a interface Serializable

  • Um objeto é serializável (-se implementa a interface Serializable), mesmo se sua superclasse não é. No entanto, o primeiro superclasse na hierarquia da classe serializável, que não implementa a interface Serializable, deve ter um construtor no-arg. Se esta for violada, readObject () irá produzir um java.io.InvalidClassException em tempo de execução

  • Todos os tipos primitivos são serializáveis.

  • campos transitórios (com modificador transiente) não são serializado, (ou seja, não salvo ou restaurado). Uma classe que implementa Serializable deve marcar campos transitórios de classes que não suportam a serialização (por exemplo, um fluxo de arquivo).

  • Os campos estáticos (com modificador estático) não são serializado.

Quando objeto é serializado Java Runtime Associates o número da versão de série que é chamado de serialVersionID.

Onde precisamos serialVersionID: Durante a desserialização para verificar se o emissor eo receptor são compatíveis com relação ao receptor serialization.If carregado a classe com serialVersionID diferente desserialização vai acabar com InvalidClassCastException .
Uma classe serializável pode declarar a sua própria serialVersionUID explicitamente declarando um campo chamado “serialVersionUID” que deve ser estático, final, e do tipo long:.

Vamos tentar isso com um exemplo.

import java.io.Serializable;    
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String empname;
private byte empage;

public String getEmpName() {
    return name;
}
public void setEmpName(String empname) {
    this.empname = empname;
}
public byte getEmpAge() {
    return empage;
}
public void setEmpAge(byte empage) {
    this.empage = empage;
}

public String whoIsThis() {
    StringBuffer employee = new StringBuffer();
    employee.append(getEmpName()).append(" is ).append(getEmpAge()).append("
years old  "));
    return employee.toString();
}
}

Criar Serialize objeto

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Writer {
public static void main(String[] args) throws IOException {
    Employee employee = new Employee();
    employee.setEmpName("Jagdish");
    employee.setEmpAge((byte) 30);

    FileOutputStream fout = new 
FileOutputStream("/users/Jagdish.vala/employee.obj");
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(employee);
    oos.close();
    System.out.println("Process complete");
}
}

Deserializ o objeto

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, 
IOException {
    Employee employee = new Employee();
    FileInputStream fin = new 
    FileInputStream("/users/Jagdish.vala/employee.obj");
    ObjectInputStream ois = new ObjectInputStream(fin);
    employee = (Employee) ois.readObject();
    ois.close();
    System.out.println(employee.whoIsThis());
 }
}    

NOTA: Agora altere o serialVersionUID da classe Employee e salvar:

private static final long serialVersionUID = 4L;

e executar a classe Reader. Não executar a classe escritor e você receberá a exceção.

Exception in thread "main" java.io.InvalidClassException: 
com.jagdish.vala.java.serialVersion.Employee; local class incompatible: 
stream classdesc serialVersionUID = 1, local class serialVersionUID = 4
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14)

Não se preocupe, o cálculo padrão é realmente bom e suficiente para 99,9999% dos casos. E se você tiver problemas, você pode - como já foi dito - introduzir UID de como o arrise necessidade (que é altamente improvável)

Como para um exemplo onde o serialVersionUID faltando pode causar um problema:

Eu estou trabalhando em esta aplicação Java EE que é composto de um módulo da Web que usa um módulo EJB. O módulo web chama o módulo de EJB remotamente e passa um POJO que implementos Serializable como um argumento.

Esta classe POJO's foi empacotado dentro do jar EJB e dentro de seu próprio frasco no WEB-INF / lib do módulo web. Eles são realmente a mesma classe, mas quando eu empacotar o módulo EJB I desempacotar frasco deste POJO para embalá-lo em conjunto com o módulo EJB.

A chamada para o EJB estava falhando com a exceção abaixo porque eu não tinha declarado a sua serialVersionUID:

Caused by: java.io.IOException: Mismatched serialization UIDs : Source
 (Rep.
 IDRMI:com.hordine.pedra.softbudget.domain.Budget:5CF7CE11E6810A36:04A3FEBED5DA4588)
 = 04A3FEBED5DA4588 whereas Target (Rep. ID RMI:com.hordine.pedra.softbudget.domain.Budget:7AF5ED7A7CFDFF31:6227F23FA74A9A52)
 = 6227F23FA74A9A52

Eu geralmente uso serialVersionUID em um contexto: Quando eu sei que vai ser sair do contexto da máquina virtual Java.

Eu sei que isto quando eu usar ObjectInputStream e ObjectOutputStream para a minha candidatura ou se eu conheço um uso da biblioteca / quadro vou usá-lo. O serialVersionID garante diferente Java VMs de versões diferentes ou fornecedores vai inter-operar corretamente ou se ele é armazenado e recuperado fora da VM por exemplo HttpSession os dados da sessão pode permanecer mesmo durante um reinício e atualização do servidor de aplicativos.

Para todos os outros casos, eu uso

@SuppressWarnings("serial")

desde que a maioria das vezes o serialVersionUID padrão é suficiente. Isto inclui Exception, HttpServlet.

Os dados de campo representa algumas informações armazenadas na classe. Classe implementa a interface Serializable, assim eclipse automaticamente oferecido para declarar o campo serialVersionUID. Vamos começar com valor 1 jogo lá.

Se você não quer que a advertência para vir, use o seguinte:

@SuppressWarnings("serial")

serialVersionUID é usado para controle de versão de objeto. você pode especificar serialVersionUID no seu arquivo de classe também. Conseqüência de não especificar serialVersionUID é que quando você adicionar ou modificar qualquer campo na classe então a classe já serializados não será capaz de recuperar porque serialVersionUID gerado para nova classe e para o velho objeto serializado será diferente. processo de serialização Java conta com serialVersionUID correto para recuperar estado de objeto serializado e joga java.io.InvalidClassException em caso de serialVersionUID incompatibilidade

Leia mais: http://javarevisited.blogspot.com/ 2011/04 / top-10-java-serialização-interview.html # ixzz3VQxnpOPZ

Seria bom se CheckStyle poderia verificar se o serialVersionUID de uma classe que implementa Serializable tem um bom valor, ou seja, que coincide com o que o gerador de ID versão de série iria produzir. Se você tem um projeto com lotes de DTOs serializáveis, por exemplo, lembrar-se de excluir o serialVersionUID existente e regenerá-lo é uma dor, e atualmente a única maneira (que eu saiba) para verificar isso é para regenerar para cada classe e comparar com o antigo. Isto é muito, muito dolorosa.

Por que usar SerialVersionUID dentro classe Serializable em Java?

Durante serialization, Java runtime cria um número de versão para uma classe, de modo que ele pode de-serializar-lo mais tarde. Esse número de versão é conhecida como SerialVersionUID em Java.

SerialVersionUID é usado para dados de versão serializada. Você só pode de-serialize uma classe se for partidas SerialVersionUID com a instância serializada. Quando não declarar SerialVersionUID na nossa classe, runtime Java gera para nós, mas não é recomendado. É recomendado para SerialVersionUID declarar como variável private static final long para evitar mecanismo padrão.

Quando você declarar uma classe como Serializable através da implementação de marcador de interface java.io.Serializable, Java Runtime persistem instância dessa classe em disco usando mecanismo de serialização padrão, desde que não tenha personalizado o processo usando a interface Externalizable.

Por uso serialVersionUID dentro classe Serializable em Java

Código: javassist.SerialVersionUID

Se você quiser alterar um grande número de classes que não tinham set serialVersionUID em primeiro lugar, enquanto manter a compatibilidade com as classes de idade, ferramentas como IntelliJ Idea, Eclipse aquém como eles gerar números aleatórios e não funciona em um monte de arquivos de uma só vez. Eu venho até o seguinte script bash (eu sinto muito por usuários do Windows, considere comprar um Mac ou convertido ao Linux) para fazer altera questão serialVersionUID com facilidade:

base_dir=$(pwd)                                                                  
src_dir=$base_dir/src/main/java                                                  
ic_api_cp=$base_dir/target/classes                                               

while read f                                                                     
do                                                                               
    clazz=${f//\//.}                                                             
    clazz=${clazz/%.java/}                                                       
    seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
    perl -ni.bak -e "print $_; printf qq{%s\n}, q{    private $seruidstr} if /public class/" $src_dir/$f
done

você salvar o presente roteiro, dizer add_serialVersionUID.sh para você ~ / bin. Então você executá-lo no diretório raiz do seu projeto Maven ou Gradle como:

add_serialVersionUID.sh < myJavaToAmend.lst

Esta .lst inclui a lista de arquivos java para adicionar o serialVersionUID no seguinte formato:

com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java

Este script usa a ferramenta JDK serialver sob o capô. Portanto, verifique se o seu $ JAVA_HOME / bin está no PATH.

Esta questão é muito bem documentado em Effective Java por Joshua Bloch. Um bom livro e uma leitura obrigatória. Vou descrever algumas das razões abaixo:

O tempo de execução de serialização aparece com um número chamado versão de série para cada classe serializável. Este número é chamado serialVersionUID. Agora existe alguma matemática por trás deste número e ele sai com base nos campos / métodos que são definidos na classe. Para a mesma classe a mesma versão é gerado a cada vez. Este número é usado durante deserialização para verificar que o remetente e o receptor de um objecto em série têm classes carregadas para esse objecto que são compatíveis com respeito a serialização. Se o receptor tiver sido carregado uma classe para o objecto que tem um serialVersionUID diferente do que a classe do remetente correspondente, em seguida, deserialização vai resultar em uma InvalidClassException.

Se a classe é serializável você também pode declarar a sua própria serialVersionUID explicitamente declarando um campo chamado "serialVersionUID" que deve ser estático, final, e do tipo long. A maioria IDE como Eclipse ajuda você gerar essa longa seqüência.

Cada vez que um objeto é serializado do objeto é marcado com um número de versão ID para o objeto class.This ID é chamado serialVersionUID e é calculado com base em informações sobre a estrutura de classe. Suponha que você fez uma classe Employee e tem versão id # 333 (atribuído pela JVM), Agora, quando você vai serializar o objeto da classe (objeto Employee suponho), JVM irá atribuir UID a ele como nº 333.

Considere uma situação - no futuro você precisa editar ou mudar a sua classe e, nesse caso, quando você modificá-lo, JVM irá atribuir-lhe um novo UID (Suponha # 444). Agora, quando você tentar desserializar o objeto empregado, JVM irá comparar (Employee objeto) identificação de versão serializada do objeto (# 333) com o da classe i # 444 (Desde que foi alterado). Em comparação JVM vai encontrar tanto a versão UID são diferentes e, portanto, Deserialization falhará. Portanto, se serialVersionID para cada classe é definida por si só programador. Será mesma, mesmo se a classe está evoluindo no futuro e, portanto, JVM vai sempre encontrar essa classe é compatível com objeto serializado mesmo que a classe é alterado. Para mais informações você pode consultar o capítulo 14 da primeira cabeça JAVA.

Uma explicação simples:

  1. Você serialização de dados?

    A serialização é basicamente a gravação de dados de classe em um arquivo / stream / etc. De-serialização está lendo os dados de volta a uma classe.

  2. Você pretende entrar em produção?

    Se você está apenas testando algo com os dados / falsos sem importância, então não se preocupe com isso (a menos que você está testando serialização diretamente).

  3. Esta é a primeira versão?

    Se assim for, serialVersionUID=1L set.

  4. É este o segundo, terceiro, etc. versão prod?

    Agora você precisa se preocupar com serialVersionUID, e deve analisá-la em profundidade.

Basicamente, se você não atualizar a versão corretamente quando você atualizar uma classe que você precisa para leitura / gravação, você receberá um erro quando você tenta ler dados antigos.

Para dizer a longa história curta deste campo é usado para verificar se os dados serializados pode ser desserializado corretamente. Serialização e desserialização são muitas vezes feitas por diferentes cópias do programa - por exemplo convertidos Object Server para cordas e clientes convertidos receberam corda para objeto. Este campo informa que tanto opera com a mesma ideia sobre o que esse objeto é. Este campo ajuda quando:

  • Você tem muitas cópias diferentes de seu programa em lugares diferentes (como um servidor e 100 clientes). Se você vai mudar o seu objeto, alterar o número da versão e se esqueça de atualizar um ISTO clientes, ele vai saber que ele não é capaz de desserialização

  • tiver guardado os seus dados em algum arquivo e depois tentar abri-lo com a versão atualizada de seu programa com objeto modificado - você vai saber que esse arquivo não é compatível, se você manter a sua versão direita

Quando é que é importante?

A mais óbvia -. Se você adicionar alguns campos para o seu objeto, versões mais antigas não será capaz de usá-los porque eles não têm esses campos em sua estrutura objeto

Menos óbvio - Quando você desserializar objeto, os campos que onde não está presente na cadeia será mantido como NULL. Se você tem campo removido do seu objeto, versões mais antigas irá manter este campo como hair-NULL que pode levar ao mau comportamento se as versões mais antigas contam com dados neste campo (de qualquer maneira que você criou-lo para alguma coisa, não só por diversão :-))

Pelo menos óbvia - Às vezes você mudar a idéia que você colocou no sentido de algum campo. Por exemplo, quando você é 12 anos de idade que você quer dizer "bicicleta" em "bicicleta", mas quando você tem 18 anos você quer dizer "motocicleta" - se seus amigos vão convidá-lo para "passeio de bicicleta através da cidade" e você será o único que veio de bicicleta, você vai undestand o quanto é importante para manter mesmo significado através dos campos: -)

Em primeiro lugar para responder à sua pergunta, quando não declarar serialVersionUID na nossa classe, runtime Java gera para nós, mas esse processo é sensível a muitos dados de classe meta incluindo o número de campos, tipo de campos, modificador de acesso de campos , interface implementada pela classe etc. Portanto, recomenda-se declará-la nós mesmos e Eclipse é avisando sobre o mesmo.

A serialização: Muitas vezes o trabalho com objetos importantes cujo estado (dados nas variáveis ??do objeto) é tão importante que não podemos arriscar a perdê-lo devido a falhas de energia / sistema (ou) falhas de rede em caso de enviar o estado do objeto para outra máquina. A solução para este problema é chamado de "Persistência", que significa simplesmente que persiste (segurando / guardar) os dados. Serialização é uma das muitas outras maneiras de conseguir persistência (salvando dados no disco / memória). Ao salvar o estado do objeto, é importante para criar uma identidade para o objeto, para ser capaz de lê-lo corretamente para trás (de-serialização). Esta identificação única é ID é serialVersionUID.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top