web-dev-qa-db-fra.com

Utilisez serialVersionUID ou supprimez les avertissements?

Je veux créer une classe qui, par exemple, étend HttpServlet? Mon compilateur m'avertit que ma classe doit avoir un serialVersionUID. Si je sais que cet objet ne sera jamais sérialisé, dois-je le définir ou ajouter une annotation pour supprimer ces avertissements?

Que feriez-vous et pourquoi?

66
Okami

Je ne sais pas Java meilleures pratiques, mais il me vient à l'esprit que si vous prétendez que la sérialisation ne se produira jamais, vous pouvez ajouter une méthode writeObject qui lance. Ensuite, supprimez l'avertissement, en toute sécurité dans la connaissance qu'il ne peut pas s'appliquer à vous.

Sinon, quelqu'un pourrait à l'avenir sérialiser votre objet via la classe parent et se retrouver avec un formulaire sérialisé par défaut où:

  • le formulaire n'est pas compatible entre les différentes versions de votre code.
  • vous avez supprimé l'avertissement que c'est le cas.

L'ajout d'un identifiant ressemble à un bodge, car ce que vous voulez vraiment faire n'est pas sérialiser. Attendre des appelants qu'ils ne sérialisent pas votre objet signifie que vous vous attendez à ce qu'ils "sachent" quand leur HttpServlet est de votre classe. Cette violation du polymorphisme est sur votre tête pour avoir un objet sérialisable qui ne doit pas être sérialisé, et le moins que vous puissiez faire est de vous assurer que les appelants imprudents le savent.

27
Steve Jessop

Si vous ne prévoyez pas de sérialiser les instances, ajoutez un SuppressWarning.

Un ID de série généré peut être un peu dangereux. Il suggère que vous lui ayez intentionnellement donné un numéro de série et qu'il soit sauvegardé pour sérialiser et désérialiser. Il est facile d'oublier de mettre à jour le numéro de série dans une version plus récente de votre application où votre classe est modifiée. La désérialisation échouera si les champs de classe ont été modifiés. Avoir un SuppressWarning indique au moins au lecteur de votre code que vous n'aviez pas l'intention de sérialiser cette classe.

18
Benno Richters

Je refuse d'être terrorisé par Eclipse pour ajouter de l'encombrement à mon code!

Je viens de configurer Eclipse pour ne pas générer d'avertissements sur serialVersionUID manquant.

14
ykaganovich

Merci @ Steve Jessop pour sa réponse à ce sujet. C'était 5 lignes de code ... à peine un problème.

J'ai ajouté @SuppressWarnings("serial") juste au-dessus de la classe en question.

J'ai également ajouté cette méthode:

private void writeObject(ObjectOutputStream oos) throws IOException {
   throw new IOException("This class is NOT serializable.");
}

J'espère que c'est ce que voulait dire Steve :)

9
Mike

Même si vous savez que cet objet sera sérialisé, il n'est pas nécessaire de générer serialVersionUID car Java le générera automatiquement pour vous et gardera automatiquement une trace des modifications afin que votre sérialisation fonctionne toujours très bien. ne doit le générer que si vous savez ce que vous faites (compatibilité de sérialisation en amont, suivi manuel des modifications, etc.)

Je dirais donc que la suppression de l'avertissement est la solution la meilleure et la plus sûre dans la plupart des cas.

6
serg

Il est bon de générer SVUID pour chaque classe implémentant sérialisable. La raison est simple. Vous jamais savez quand il sera sérialisé par vous ou par un tiers. Il peut être configuré de nombreux services qui sérialiseront les servlets. Pour chaque IDE existe un plugin qui génère un ou utilisez simplement un modèle et définissez svuid = 1L.

4
Rastislav Komara

Cet avertissement me rend fou, car chaque fois que vous sous-classe une classe Swing, vous savez vous n'allez jamais la sérialiser, mais il y a cet avertissement stupide. Mais oui, je laisse Eclipse en générer un.

3
Paul Tomblin

Laissez Eclipse générer un ID. Rapide et facile. Les avertissements ne doivent pas être ignorés. Vous évite également beaucoup de problèmes si vous veniez au point où l'objet/doit/être sérialisé.

2
xmjx

Veuillez suivre ce lien pour obtenir des explications détaillées: http://technologiquepanorama.wordpress.com/2009/02/13/what-is-use-of-serialversiouid/

2
harshit

Ça dépend.

Si vous utilisez plusieurs compilateurs pour compiler votre code source plusieurs fois, votre code compilé peut avoir différents ID de sérialisation qui interrompent la sérialisation. Ensuite, vous devez vous en tenir à un serializationId constant explicitement dans votre code. Il doit être statique et final et par classe (non héritable).

Cependant, si vous compilez toujours votre code avec un compilateur spécifique et déployez toujours votre code d'un coup sur toutes vos machines virtuelles, vous avez probablement besoin d'une vérification de version stricte et vous voulez vous assurer qu'à chaque fois qu'une seule version de votre code est en cours d'exécution, dans dans ce cas, vous devez simplement supprimer l'avertissement. Donc, dans le cas où un VM n'est pas déployé avec succès et exécute l'ancienne version de votre code, vous vous attendez probablement à une exception pendant la sérialisation plutôt qu'à exciter les objets désérialisés. Cela se trouve être mon cas, nous avons l'habitude de ont un très très grand cluster et nous avons besoin d'une vérification de version stricte pour détecter tout problème de déploiement.

Quoi qu'il en soit, vous devriez probablement éviter la sérialisation dans la mesure du possible, car la sérialisation par défaut est très lente par rapport aux tampons de protocole ou à l'épargne et ne prend pas en charge l'interopérabilité entre les langues.

2
Daniel

Si vous omettez un serialVersionUID Java en générera un pour la classe au moment de la compilation (il change à chaque compilation).

Lors de la désérialisation d'objets, le serialVersionUID de l'objet désérialisé est comparé à celui de la classe dans le jvm. S'ils sont différents, ils sont considérés comme incompatibles et une exception est levée. Cela peut se produire par exemple après la mise à niveau de votre programme et la désérialisation des anciennes classes.

J'utilise toujours 1L pour serialversionUID. Cela ne fait pas de mal (par rapport à la valeur par défaut générée) et laisse toujours la possibilité de briser la compatibilité plus tard en incrémentant l'id.

2
Glever

Si vous savez que vos applications ne sérialisent jamais les choses, supprimez l'avertissement à l'échelle de l'application. Cela peut être fait en utilisant des arguments de ligne de commande javac:

javac -Xlint -Xlint:-serial *******

De cette façon, vous aurez tous les avertissements sauf "série". Les IDE et les outils de construction comme Maven/SBT/Gradle fonctionnent très bien avec cela.

1
VasiliNovikov