IntelliJ IDEA que genera serialVersionUID

297

¿Cómo generar este valor en IntelliJ IDEA?

Voy a Configuración -> Errores -> Problemas de serialización -> Clase serializable sin 'serialVersionUID', pero aún no me muestra la advertencia. Mi clase PKladrBuilding padre implementa la interfaz Serializable .

Parte del código:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
Kirill Bazarov
fuente
3
¿Estás seguro de que necesitas generar un valor, en lugar de definir el tuyo? Si está creando una nueva clase, le recomendaría que defina, por ejemplo, 1Lcomo su ID e incremente cuando cambie su forma serializada. (Ver stackoverflow.com/questions/888335/… ).
Duncan Jones
1
stackoverflow.com/questions/24573643/… tiene una muy buena solución.
Pankaj Kumar

Respuestas:

588

No estoy seguro si tiene una versión anterior de IntelliJ IDEA, pero si voy al menú ArchivoConfiguración ...InspeccionesProblemas de serialización → Clase serializable sin 'serialVersionUID' habilitado, la clase que proporciona me da advertencias.

Ingrese la descripción de la imagen aquí

Si pruebo la primera clase, veo:

Ingrese la descripción de la imagen aquí

Por cierto: no me mostró una advertencia hasta que agregué { }al final de cada clase para corregir el error de compilación.

Peter Lawrey
fuente
2
Probar File| Invalidate Caches, si no ayuda, póngase en contacto con [email protected] con un proyecto de muestra para reproducir.
CrazyCoder
1
Marque idea.log(Ayuda | Revelar Iniciar sesión ...) para ver las excepciones, se sabe que el directorio de inicio cifrado en Linux causa problemas debido al error del kernel .
CrazyCoder
1
Tengo muchas excepciones allí ... como java.lang.NoClassDefFoundError: org / intellij / lang / annotations / MagicConstant;
Kirill Bazarov el
2
He reinstalado IDEA y eliminado los complementos y me ayuda. Muchas gracias.
Kirill Bazarov
55
La forma en que lo hice funcionar en la v15 es pasar el mouse sobre el ClassName para ver la advertencia y mover el mouse lentamente hacia la canaleta. En ese punto, la "bombilla" aparece en la pantalla. (Intente esto varias veces si no funciona como se pretendía la primera vez). Luego puede hacer clic en la opción Crear campo para crear el uid. Espero que esto ayude a las personas que están atrapadas en esto.
Niyaz
173

Instale el complemento GenerateSerialVersionUID de Olivier Descout.

Vaya a: menú ArchivoConfiguraciónComplementosBuscar repositoriosGenerateSerialVersionUID

Instale el complemento y reinicie.

Ahora puede generar la identificación desde el menú CódigoGenerar → serialVersionUID` o el acceso directo.

Sileria
fuente
14
¿Debería uno necesitar un complemento externo realmente para que esto funcione?
H.Rabiee
Sí, necesita un complemento que ya forma parte del repositorio de complementos IntelliJ.
Sileria
Trabajó para mí en Intellij IDEA 12.1
Sagar Hatekar
Funciona para mí en 13.0.2.
user1978019
Funciona en Android Studio 0.8.9
Itai Hanski
67

Sin complementos: solo necesita habilitar el resaltado en IntelliJ:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'- Establecer bandera y hacer clic 'OK'.

Ahora, si su clase se implementa Serializable, verá resaltado, y alt+Enterel nombre de la clase propondrá generar private static final long serialVersionUID.

PD: tomado de aquí

Nikhil Katre
fuente
44
Gracias. No sé por qué no veo la bombilla, pero hacer clic en el nombre de la clase y escribir Alt-Enter es el truco.
John S
2
Respuesta es robado de aquí
Serhii Maksymchuk
esto es más actualizado
Christian Matthew
39

Después de pasar un tiempo en serialización, encuentro que no deberíamos generar serialVersionUID con algún valor aleatorio, deberíamos darle un valor significativo.

Aquí hay un comentario detallado sobre esto. Estoy haciendo frente al comentario aquí.

En realidad, no debería estar "generando" UID de versión en serie. Es una "característica" tonta que se deriva del malentendido general de cómo Java usa esa identificación. Debería proporcionar a estos ID valores significativos y legibles, por ejemplo, comenzando con 1L e incrementándolos cada vez que piense que la nueva versión de la clase debería dejar obsoletas todas las versiones anteriores (que podrían estar serializadas previamente). Todas las utilidades que generan tales ID básicamente hacen lo que hace la JVM cuando la ID no está definida: generan el valor basado en el contenido del archivo de clase, por lo tanto, generan enteros largos sin sentido ilegibles. Si desea que todas y cada una de las versiones de su clase sean distintas (a los ojos de la JVM), entonces ni siquiera debe especificar el valor serialVersionUID, ya que la JVM producirá una sobre la marcha, y el valor de cada versión de tu clase será único. El propósito de definir ese valor explícitamente es decirle al mecanismo de serialización que trate las diferentes versiones de la clase que tienen el mismo SVUID como si fueran iguales, por ejemplo, no rechazar las versiones serializadas más antiguas. Entonces, si define la ID y nunca la cambia (y supongo que eso es lo que hace, ya que confía en la generación automática, y probablemente nunca vuelva a generar sus ID), se asegurará de que todas, incluso las versiones absolutamente diferentes, de su clase será considerada igual por el mecanismo de serialización. ¿Es eso lo que quieres? Si no es así, y si realmente desea tener control sobre cómo se reconocen sus objetos, debe utilizar valores simples que usted mismo pueda comprender y actualizar fácilmente cuando decida que la clase ha cambiado significativamente.

Espero que esto ayude. Buena suerte.

Emdadul Sawon
fuente
2
¡Gracias, me salteé este simple hecho durante tanto tiempo!
Dedek
1
En realidad, volvería a generar el serialVersionUIDcon un nuevo número aleatorio cuando no quiero admitir versiones antiguas en la deserialización. Quizás no necesito usar números aleatorios, pero puedo comenzar con 1 e incrementarlo. Sin embargo, 3Lno tiene más significado para mí entonces -3518231192373568183L. Por lo tanto, supongo que ambas soluciones funcionan de manera similar. Sin embargo, el número aleatorio podría tener la ventaja de que funciona en historias no lineales con horquillas y ramas.
JojOatXGME
16

Para generar el valor use

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

y proporcione la variable de plantilla randomLong con el siguiente valor: groovyScript ("new Random (). nextLong (). abs ()")

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

Pharsfalvi
fuente
1
Me encanta este comentario, usar plantillas en vivo es sin duda la solución más rápida y más personalizable (eliminé la nueva línea, por ejemplo). Para configurar, vaya a Android Studio> Preferencias> Editor> Plantillas en vivo y cree una nueva allí (icono más) con este valor y use las variables de edición para ingresar el script
hcpl
13

Además, puede agregar una plantilla en vivo que hará el trabajo.

Para hacerlo, presione Ctrl+Alt+S-> "Live Templates"sección -> other(o w / e que desee)

Y luego cree uno nuevo con una definición como esta:

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

Luego seleccione el definitionalcance y guárdelo como'serial'

Ahora puede escribir serialTABen el cuerpo de la clase.

fallens4e
fuente
3

Otra forma de generar el serialVersionUID es usarlo >Analyze >Run Inspection by Namedesde el menú contextual (o el atajo de teclado, que es ctrl+ alt+ shift+ ipor defecto) y luego escribir "Clase serializable sin 'serialVersionUID'" (o simplemente escribir "serialVersionUID" y el tipo que está más adelante) La función lo encontrará por usted.

Idea> Analizar> Ejecutar inspección por nombre Luego obtendrá un menú contextual en el que puede elegir dónde ejecutar las inspecciones (por ejemplo, todo desde un módulo específico, proyecto completo, un archivo, ...)

Con este enfoque, ni siquiera tiene que establecer las reglas generales de inspección en nada.

Alejandro
fuente
Bien, esto hizo el trabajo por mí. Encontró la variable que faltaba y presentó la opción de agregarla.
arenaq
@arenaq contento, esto ayudó a alguien más ;-)
Alexander
2

Con la versión v2018.2.1

Ir

Preferencia> Editor> Inspecciones> Java> Problemas de serialización> alternar "Clase serializable sin 'serialVersionUID'".

Debería aparecer una advertencia al lado de la declaración de clase.

YLyu
fuente
1

Estoy usando Android Studio 2.1 y tengo una mejor consistencia para obtener la bombilla haciendo clic en el Nombre de la clase y pasando el mouse por un segundo.

Johnny Wu
fuente
1

Agregue una plantilla en vivo llamada "ser" al otro grupo, configúrela como "Aplicable en Java: declaración" y desmarque "Acortar nombres FQ". Dele un texto de plantilla de solo:

$serial$

Ahora edite las variables y configure serial a:

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())

Asume el diseño estándar del proyecto Gradle. Cambiar / construir / a / objetivo / para Maven.

Greg Allen
fuente
1

Método moderno más fácil: Alt+ Enteren

private static final long serialVersionUID = ;

IntelliJ subrayará el espacio después de =. coloca el cursor sobre él y presiona alt+ Enter( Option+ Enteren Mac). Obtendrá una ventana emergente que dice "Cambiar aleatoriamente el inicializador serialVersionUID". Simplemente presione enter, y se llenará ese espacio con un largo aleatorio.

jeremysprofile
fuente
0

Si desea agregar el serialVersionUID ausente para un grupo de archivos, IntelliJ IDEA puede no funcionar muy bien. Presento un script simple para cumplir este objetivo con facilidad:

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

Guarda este script, digamos como add_serialVersionUID.shen su ~/bincarpeta. Luego lo ejecuta en el directorio raíz de su proyecto Maven o Gradle como:

add_serialVersionUID.sh < myJavaToAmend.lst

Este .lst incluye la lista de archivos Java para agregar el serialVersionUID en el siguiente 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 la herramienta JDK serialVer. Es ideal para una situación en la que desea modificar una gran cantidad de clases que no tenían un serialVersionUID establecido en primer lugar, manteniendo la compatibilidad con las clases antiguas.

schnell18
fuente