IntelliJ IDEA générant serialVersionUID

297

Comment générer cette valeur dans IntelliJ IDEA?

Je vais dans Paramètres -> Erreurs -> Problèmes de sérialisation -> Classe sérialisable sans 'serialVersionUID', mais il ne me montre toujours pas l'avertissement. Ma classe PKladrBuilding parent implémente l' interface Serializable .

Une partie du code:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
Kirill Bazarov
la source
3
Êtes-vous sûr de devoir générer une valeur plutôt que de définir la vôtre? Si vous créez une nouvelle classe, je vous recommanderais de définir par 1Lexemple votre ID et incrémenter lorsque votre formulaire sérialisé change. (Voir stackoverflow.com/questions/888335/… ).
Duncan Jones
1
stackoverflow.com/questions/24573643/… a une très bonne solution.
Pankaj Kumar

Réponses:

589

Je ne sais pas si vous avez une ancienne version d'IntelliJ IDEA, mais si je vais dans le menu FichierParamètres ...InspectionsProblèmes de sérialisation → Classe sérialisable sans 'serialVersionUID'` activée, la classe que vous fournissez me donne des avertissements.

Entrez la description de l'image ici

Si j'essaie le premier cours, je vois:

Entrez la description de l'image ici

BTW: Il ne m'a pas montré d'avertissement jusqu'à ce que j'ajoute { }à la fin de chaque classe pour corriger l'erreur de compilation.

Peter Lawrey
la source
2
Essayez File| Invalidate Caches, si cela n'aide pas, contactez [email protected] avec un exemple de projet à reproduire.
CrazyCoder
1
Vérifiez idea.log(Aide | Révéler la connexion ...) pour les exceptions, le répertoire personnel chiffré sous Linux est connu pour causer des problèmes en raison du bogue du noyau .
CrazyCoder
1
j'ai beaucoup d'exceptions là-bas .. comme java.lang.NoClassDefFoundError: org / intellij / lang / annotations / MagicConstant;
Kirill Bazarov
2
J'ai réinstallé IDEA et supprimé les plug-ins et cela m'aide. Merci beaucoup.
Kirill Bazarov
5
La façon dont je l'ai fait fonctionner dans la v15 est de survoler le ClassName pour voir l'avertissement et de déplacer lentement ma souris vers la gouttière. À ce stade, "l'ampoule" apparaît sur l'écran. (Essayez ceci plusieurs fois si cela ne fonctionne pas comme prévu la première fois). Ensuite, vous pouvez cliquer sur l'option de création de champ pour créer l'uid. J'espère que cela aide les gens qui sont coincés à ce sujet.
Niyaz
173

Installez le plugin GenerateSerialVersionUID par Olivier Descout.

Accédez à: menu FichierParamètresPluginsParcourir les référentielsGenerateSerialVersionUID

Installez le plugin et redémarrez.

Vous pouvez maintenant générer l'identifiant à partir du menu CodeGénérer → serialVersionUID` ou le raccourci.

Sileria
la source
14
Faut-il vraiment avoir besoin d'un plugin externe pour que cela fonctionne?
H.Rabiee
Oui, vous avez besoin d'un plugin qui fait déjà partie du référentiel de plugins IntelliJ.
Sileria
A travaillé pour moi sur Intellij IDEA 12.1
Sagar Hatekar
Fonctionne pour moi sur 13.0.2.
user1978019
Fonctionne sur Android Studio 0.8.9
Itai Hanski
67

Sans aucun plugin: il vous suffit d'activer la mise en évidence dans IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'- définir le drapeau et cliquer 'OK'.

Maintenant, si votre classe implémente Serializable, vous verrez le surlignage et alt+Enterle nom de la classe proposera de générer private static final long serialVersionUID.

PS: Pris d' ici

Nikhil Katre
la source
4
Merci. Je ne sais pas pourquoi je ne vois pas l'ampoule, mais cliquer sur le nom de la classe et taper Alt-Entrée fait l'affaire.
John S
2
La réponse est volée d' ici
Serhii Maksymchuk
c'est plus à jour
Christian Matthew
39

Après avoir passé un certain temps sur la sérialisation, je trouve que nous ne devons pas générer serialVersionUIDavec une valeur aléatoire, nous devons lui donner une valeur significative.

Voici un commentaire détaillé à ce sujet. J'adopte le commentaire ici.

En fait, vous ne devez pas "générer" d'UID de version série. C'est une "fonctionnalité" stupide qui découle de la méconnaissance générale de la façon dont cet ID est utilisé par Java. Vous devez donner à ces ID des valeurs significatives et lisibles, par exemple en commençant par 1L, et les incrémenter chaque fois que vous pensez que la nouvelle version de la classe doit rendre obsolètes toutes les versions précédentes (qui pourraient être sérialisées auparavant). Tous les utilitaires qui génèrent de tels ID font essentiellement ce que fait la JVM lorsque l'ID n'est pas défini: ils génèrent la valeur en fonction du contenu du fichier de classe, créant ainsi des entiers longs sans signification illisibles. Si vous voulez que chaque version de votre classe soit distincte (aux yeux de la JVM), vous ne devez même pas spécifier la valeur serialVersionUID car la JVM en produira une à la volée, et la valeur de chaque version de votre classe sera unique. Le but de définir explicitement cette valeur est de dire au mécanisme de sérialisation de traiter les différentes versions de la classe qui ont le même SVUID comme si elles étaient les mêmes, par exemple de ne pas rejeter les anciennes versions sérialisées. Donc, si vous définissez l'ID et que vous ne le changez jamais (et je suppose que c'est ce que vous faites puisque vous comptez sur la génération automatique et que vous ne régénérez probablement jamais vos ID), vous vous assurez que toutes les versions - même absolument différentes - de votre classe sera considérée comme la même par le mécanisme de sérialisation. Est-ce que c'est ce que tu veux? Sinon, et si vous souhaitez en effet contrôler la façon dont vos objets sont reconnus, vous devez utiliser des valeurs simples que vous pouvez comprendre et mettre à jour facilement lorsque vous décidez que la classe a changé de manière significative.

J'espère que cela t'aides. Bonne chance.

Emdadul Sawon
la source
2
Merci, je sautais ce simple fait depuis si longtemps!
dedek
1
En fait, je recréerais le serialVersionUIDavec un nouveau nombre aléatoire lorsque je ne veux pas prendre en charge les anciennes versions sur la désérialisation. Je n'ai peut-être pas besoin d'utiliser des nombres aléatoires, mais je peux commencer par 1 et l'incrémenter. Cependant, 3Lcela n'a plus de sens pour moi -3518231192373568183L. Par conséquent, je suppose que les deux solutions fonctionnent de manière similaire. Le nombre aléatoire pourrait cependant avoir l'avantage de fonctionner sur des histoires non linéaires avec des fourches et des branches.
JojOatXGME
16

Afin de générer la valeur d'utilisation

private static final long serialVersionUID = $randomLong$L;
$END$

et fournissez la variable de modèle randomLong avec la valeur suivante: groovyScript ("new Random (). nextLong (). abs ()")

https://pharsfalvi.wordpress.com/2015/03/18/adding-serialversionuid-in-idea/

pharsfalvi
la source
1
J'adore ce commentaire, en utilisant des modèles en direct, c'est à coup sûr la solution la plus rapide et la plus personnalisable (j'ai supprimé la nouvelle ligne par exemple). Pour configurer, allez dans Android Studio> Préférences> Éditeur> Modèles en direct et créez-en un nouveau (icône plus) avec cette valeur et utilisez les variables d'édition pour entrer le script
hcpl
13

De plus, vous pouvez ajouter un modèle en direct qui fera le travail.

Pour ce faire, appuyez sur Ctrl+Alt+S-> "Live Templates"section -> other(ou w / e que vous souhaitez)

Et puis créez-en un nouveau avec une définition comme celle-ci:

private static final long serialVersionUID = 1L;
$END$

Sélectionnez ensuite la definitionportée et enregistrez-la sous'serial'

Vous pouvez maintenant saisir le serialTABcorps de la classe.

fallens4e
la source
3

Une autre façon de générer le serialVersionUID est d'utiliser à >Analyze >Run Inspection by Namepartir du menu contextuel (ou du raccourci clavier, qui est ctrl+ alt+ shift+ ipar défaut), puis de taper "Classe sérialisable sans 'serialVersionUID'" (ou simplement de taper "serialVersionUID" et le type à venir la fonction le trouvera pour vous.

Idée> Analyser> Exécuter l'inspection par nom Vous obtiendrez alors un menu contextuel où vous pourrez choisir où exécuter les inspections (par exemple, tous à partir d'un module spécifique, d'un projet entier, d'un fichier, ...)

Avec cette approche, vous n'avez même pas besoin de définir les règles générales d'inspection.

Alexandre
la source
Bien, cela a fait le travail pour moi. Il a trouvé la variable manquante et a présenté l'option de l'ajouter.
arenaq
@arenaq content, cela a aidé quelqu'un d'autre ;-)
Alexander
2

Avec version v2018.2.1

Aller à

Préférence> Éditeur> Inspections> Java> Problèmes de sérialisation> basculez "Classe sérialisable sans 'serialVersionUID'".

Un avertissement doit apparaître à côté de la déclaration de classe.

YLyu
la source
1

J'utilise Android Studio 2.1 et j'ai une meilleure cohérence pour obtenir l'ampoule en cliquant sur le nom de la classe et en la survolant pendant une seconde.

Johnny Wu
la source
1

Ajoutez un modèle en direct appelé "ser" à l'autre groupe, définissez-le sur "Applicable en Java: déclaration" et décochez "Raccourcir les noms FQ". Donnez-lui un modèle de texte juste:

$serial$

Maintenant, éditez les variables et définissez série sur:

groovyScript("(System.env.JDK_HOME+'/bin/serialver -classpath '+com.intellij.openapi.fileEditor.FileDocumentManager.instance.getFile(_editor.document).path.replaceAll('/java/.*','').replaceAll('/src/','/build/classes/')+' '+_1).execute().text.replaceAll('.*: *','')",qualifiedClassName())

Il suppose la disposition standard du projet Gradle. Changez / build / en / target / pour Maven.

Greg Allen
la source
1

Méthode moderne la plus simple: Alt+ Enteractivée

private static final long serialVersionUID = ;

IntelliJ soulignera l'espace après le =. placez votre curseur dessus et appuyez sur alt+ Enter( Option+ Entersur Mac). Vous obtiendrez un popover qui dit "Changer au hasard l'initialiseur serialVersionUID". Appuyez simplement sur Entrée, et cela remplira cet espace avec une longue aléatoire.

jeremysprofile
la source
0

Si vous souhaitez ajouter le serialVersionUID absent pour un tas de fichiers, IntelliJ IDEA peut ne pas fonctionner très bien. Je propose un script simple pour atteindre facilement cet objectif:

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

Vous enregistrez ce script, dites comme add_serialVersionUID.shdans votre ~/bindossier. Ensuite, vous l'exécutez dans le répertoire racine de votre projet Maven ou Gradle comme:

add_serialVersionUID.sh < myJavaToAmend.lst

Ce .lst inclut la liste des fichiers Java pour ajouter le serialVersionUID au format suivant:

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

Ce script utilise l'outil JDK serialVer. Il est idéal dans une situation où vous souhaitez modifier un grand nombre de classes qui n'avaient pas défini serialVersionUID en premier lieu tout en conservant la compatibilité avec les anciennes classes.

schnell18
la source