2012-10-11 33 views
14

Java contiene muchas clases (como en Swing) que implementan el dreaded and error proneinterface Serializable.¿Cuál es una buena manera de hacer que una clase sea deserializable?

Si se implementa, por ejemplo, un nuevo TableModel extendiendo AbstractTableModel, el nuevo modelo debe ser serializable pero lo que si contiene tipos de datos internos que no son serializables, y que no tiene que ser ya no piensa para usar esta característica de todos modos?

En tal caso, herramientas como Sonar enloquecen. Los dos se quejan de que "Clase Foo define el campo de instancia no transitoria no serializable bar".

así que hago ese campo transient sólo para "El campo Foo.bar es transitorio, pero no se establece de deserialización"

¿Es posible decir "No, esta clase no es serializable, y yo don' ¿Quieres que sea "de tal manera que no obtienes ningún error en herramientas como Sonar?

+0

¿El Sónar apoyo supresión de una advertencia para una clase individual? En IntelliJ le da la opción de agregar un @SuppressWarning a la clase para usted para este control. –

+0

Sonar simplemente ejecuta FindBugs, PMD y CheckStyle en su código y agrega los resultados. Entonces, una solución que mantenga a esos tres callados me funcionaría. '@ SuppressWarning' funciona como se esperaba. También hay complementos que permiten ignorar las advertencias por elementos como el nombre del archivo, la ruta o el patrón de cadena. –

+0

¿No es eso lo que es "transitorio"? – EJP

Respuesta

20

Citando de este JavaRevisited article (ver # 8):

Para evitar la serialización de Java que necesita para implementar el método writeObject() y readObject() en su clase y la necesidad de tirar de los NotSerializableException método.

lo que sólo tiene que pegar esto en su clase:

private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException { 
    throw new java.io.NotSerializableException(getClass().getName()); 
} 

private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException { 
    throw new java.io.NotSerializableException(getClass().getName()); 
} 
+0

Wow, no sabía sobre 'NotSerializableException' – AlexR

+0

He verificado esta solución y funciona. Sonar, FindBugs y PMD parecen verificar 'NotSerializableException'. –

+2

Suena extraño: implementar una interfaz serializable y lanzar una NotSerializableException, mientras se serializa. La única forma que veo es crear un Proxy-Class, que NO es serializable y delegar todos los métodos a la implementación concreta. Pero eso es algo así como aniquilar a un pequeño pajarito. –

0

lo que puedo pensar método de implementación private void writeObject() de la siguiente manera:

private void writeObject(ObjectOutputStream oos) throws IOException { 
    throw new UnsupportedOperationException("Not serializable!!!"); 
} 

alternativa, se puede aplicar Externalizable y escribir y aplicación similar de writeExternal()

Ambos son métodos no "buenas" pero sólo soluciones temporales.

1

Las respuestas que veo aquí simplemente responden si es posible evitar la serialización o la deserialización de alguna clase marcada serializable. La pregunta era diferente, sin embargo:

'¿Es posible decir "No, esta clase no es serializable, y no quiero que sea" de forma que no se obtenga ninguna errores en herramientas como Sonar? '

(lo que me pregunto acerca de esas muchas up-votos en esas respuestas ...)

Google'ing alrededor de la respuesta parece ser 'no', Sonar se puede decir que una clase de este tipo es una "falsa positivo ", pero eso requiere retocar con Sonar. Los desarrolladores que desarrollan código inspeccionado por Sonar de otras personas no pueden beneficiarse de esa posibilidad.

Y como la pregunta realmente pide una solución para otras herramientas "como Sonar", también, la respuesta en general no puede ser "Sí" --- seguramente alguna de esas herramientas insistirá en que "implementa Serializable + tiene no- campo serializable no transitorio "para significar problemas.

+1

obtienen votaciones porque proponen una solución. – Matsemann

+0

Oh, ya veo, el póster original lo probó y las herramientas en cuestión realmente buscan esa excepción. Entonces las respuestas sí implican una solución ... – mkl

1

¿Puedes usar algo como eso?

@SuppressFBWarnings(justification = "This field need to be transient") 
private transient SomeObject myTransientField; 

Suprimirá la advertencia de Findbug. También puede especificar el tipo de validación que desea suprres como:

@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") 

La lista completa está ahí: http://findbugs.sourceforge.net/bugDescriptions.html

+0

Veo lo que estás tratando de hacer pero solo tengo 'transitorio' porque FindBugs se queja de que el campo no se puede serializar. Lo que estoy buscando es una forma de decirle a Sonar que la clase no puede ni será serializada. –

Cuestiones relacionadas