Cuando serializamos objetos, los miembros estáticos no se serializan, pero si tenemos que hacerlo, ¿hay alguna salida?¿Cómo serializar los miembros de datos estáticos de una clase de Java?
Respuesta
La primera pregunta es ¿por qué necesita serializar los miembros estáticos?
Los miembros estáticos están asociados a la clase, no a las instancias, por lo que no tiene sentido incluirlos al serializar una instancia.
La primera solución es hacer que esos miembros no sean estáticos. O bien, si esos miembros son los mismos en la clase original y la clase objetivo (misma clase, pero posiblemente en entornos de tiempo de ejecución diferentes), no los serialice en absoluto.
Tengo algunas ideas sobre cómo se puede enviar a través de miembros estáticos, pero primero necesito ver el caso de uso, como en todos los casos eso significa actualizar la clase objetivo, y no he encontrado una buena razón para hacerlo asi que.
supongamos que quiero contar el número de instancia de una clase como Coche. y no estoy usando la base de datos. Así, en ese caso, después del cierre de la aplicación, debo almacenar esta información con otra información. –
¿Necesita almacenar ese número directamente? Si actualiza el número a medida que deserializa cada automóvil (anulando readObject), reflejará correctamente el número de autos en la serialización. –
Las variables estáticas se comparten entre todas las instancias de los objetos de una clase (memoria compartida). Si necesita guardar algo estático, como si tuviera una enumeración de valores diferentes y de vez en cuando cambiara un valor estático de ese tipo de enumeración, cambiar el valor guardado podría ser tan simple como tener todas las clases configuradas como variables locales a ese tipo.O podría dar un paso más, y tener un grupo de clases ampliar la clase Lo que sea, y la clase Lo que sea, podría simplemente compartir una variable local para todos sus hijos. Cuando se deserialice, puede volver a cargar sus valores estáticos como estaban. –
Los miembros estáticos pertenecen a la clase, no a los objetos individuales.
Debe reconsiderar su estructura de datos.
Puede controlar la serialización implementando:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
Hay una descripción completa de serialización http://java.sun.com/developer/technicalArticles/Programming/serialization/.
Como han dicho otras respuestas, realmente no tiene sentido serializar statics ya que es el objeto, no la clase que está serializando y necesita hacer, huele como si tuviera otros problemas con su código para mí.
Puede controlar la serialización, pero no hay ningún lugar sensato para poner datos estáticos porque no tiene ningún sentido en el contexto. –
Dado que no conocemos el contexto, no podemos decir si tiene sentido o no. Por ejemplo, después de usar la serialización predeterminada, podría tener sentido agregar el miembro estático a la transmisión. En la deserialización, uno puede establecer el miembro estático si es nulo; de lo contrario, descarte el objeto serializado. – erickson
Tom, estás abusando de "prueba por repetición", ¿verdad? ;) –
Buenas respuestas y comentarios - no lo hagas. ¿Pero cómo?
Lo más probable es que esté creando un objeto para contener todas sus "Estáticas". Ese objeto probablemente también tenga métodos estáticos de tu clase.
Cada instancia de su clase puede contener esta otra clase, o si realmente tiene que hacerlo, puede convertirlo en un singleton al que cualquier miembro puede acceder.
Después de hacer este refactorizador, encontrará que debería haberlo hecho así todo el tiempo. Incluso puede descubrir que algunas de sus limitaciones de diseño previas que lo estaban molestando en un nivel de subconcesamiento se han desvanecido.
Probablemente descubrirá que esta solución también resuelve otros problemas de serialización que aún no había notado.
Gente, estática no significa INMUTABLE. Por ejemplo, es posible que desee serializar todo el estado del cálculo (sí, incluidos los campos estáticos, contadores, etc.) para reanudarlo más tarde, después de reiniciar JVM y/o la computadora host.
La respuesta correcta a eso, como ya se dijo, es usar interfaz Externalizable, no Serializable. Entonces tienes un control completo sobre qué y cómo externalizas.
Si el estado del cálculo no está incrustado en el objeto que está serializando, entonces no debería almacenarlo como parte de la serialización de ese objeto. – DJClayworth
Mutable static generalmente significa roto. –
Piense de nuevo. ¿Qué hay de los algoritmos genéticos multiproceso, por ejemplo? El almacenamiento compartido (estático) se usa para mantener el registro de las variantes evaluadas. Que sea un singleton? Posible, pero tiene sus propios inconvenientes. –
Sí, podemos serializar las variables estáticas. Pero podemos escribir nuestro propio writeObject()
y readObject()
. Creo que esto puede resolver el problema.
Tener aplicación compacta, implementar readObject & writeObject en su llamada clase defaultReadObject & métodos defaultWriteObject dentro de esos métodos que maneja la serialización normal y luego proceder con la serialización & de-serialización lo que necesita campos adicionales.
Saludos, GK
Ésta es la serialización para el campo estático: newBookingNumber.
class Booking implements Serializable
{
/**
* Generated serial version ID.
*/
private static final long serialVersionUID = 5316748056989930874L;
// To hold new booking number.
private static int newBookingNumber = 0;
// The booking number.
private int bookingNumber;
/*
* Default serializable fields of a class are defined to be
* the non-transient and non-static fields. So, we have to
* write and read the static field separately.
*/
private void writeObject(ObjectOutputStream oos)
throws IOException
{
oos.defaultWriteObject();
oos.writeObject(new Integer(newBookingNumber));
}
private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException
{
ois.defaultReadObject();
newBookingNumber = (Integer)ois.readObject();
}
}
Usted puede hacer esto sin tener que actualizar manualmente su clase cada vez que se cambia simplemente un campo. Es posible que desee hacer esto si desea tener la facilidad de los miembros estáticos para acceder a la configuración en una aplicación, pero también desea guardar esa configuración. En este caso, también desearía tener la opción de aplicarlos a su antojo, no cargarlos de manera predeterminada ya que las otras soluciones aquí lo requieren, ya que son estáticos. Esto permite la reversión de configuraciones por razones obvias.
Básicamente, utilice los métodos de campo para obtener todos los miembros de la clase, luego asigne los nombres completos de estos campos a los contenidos. El nombre completo es obligatorio ya que Field no es serializable. Serialice esta asignación y vuelva a instalarla para obtener la configuración guardada.
La segunda parte del rompecabezas es el tipo de función apply(). Esto pasa por la asignación y aplica lo que puede a la clase estática.
También debe asegurarse de que los contenidos de los miembros estáticos sean ellos mismos serializables.
Como se puede ver con suerte en esta clase de ejemplo, los miembros estáticos se pueden guardar y devolver fácilmente. Dejaré que el implementador se preocupe por los UID de las clases, las salvaguardas, etc. isSameAs() se usa para las pruebas unitarias. AppSettings es la clase que contiene todos los campos estáticos que desea serializar.
public class AppSettingsReflectorSaver implements Serializable {
HashMap<String, Object> genericNamesAndContents = new HashMap<String, Object>();
private AppSettingsReflectorSaver() {
}
static AppSettingsReflectorSaver createAppSettingsSaver() {
AppSettingsReflectorSaver ret = new AppSettingsReflectorSaver();
ret.copyAppSettings();
return ret;
}
private void copyAppSettings() {
Field[] fields = AppSettings.class.getFields();
for (Field field : fields) {
mapContentsForSerialization(field);
}
}
private void mapContentsForSerialization(Field field) {
try {
Object fieldContents = field.get(AppSettings.class);
genericNamesAndContents.put(field.toGenericString(), fieldContents);
} catch (IllegalArgumentException ex) {
Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex);
}
}
boolean isSameAs(AppSettingsReflectorSaver now) {
for(String thisKey : genericNamesAndContents.keySet()){
boolean otherHasThisKey = now.genericNamesAndContents.containsKey(thisKey);
Object thisObject = genericNamesAndContents.get(thisKey);
Object otherObject = now.genericNamesAndContents.get(thisKey);
boolean otherHasThisValue = thisObject.equals(otherObject);
if (!otherHasThisKey || !otherHasThisValue){
return false;
}
}
return true;
}
void applySavedSettingsToStatic() {
Field[] fields = AppSettings.class.getFields();
for (Field field : fields) {
if (!genericNamesAndContents.containsKey(field.toGenericString())){
continue;
}
Object content = genericNamesAndContents.get(field.toGenericString());
try {
field.set(AppSettings.class, content);
} catch (IllegalArgumentException ex) {
Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Este es mi primer post - ir fácil en mí: P ~
- 1. Miembros de clase estáticos python
- 2. ¿Cómo acceder a los miembros estáticos de una clase?
- 3. Miembros estáticos de una clase de instancia
- 4. Bloqueo de miembros estáticos de una clase
- 5. Serializar datos de miembros privados
- 6. ¿Debo usar miembros de datos estáticos? (C++)
- 7. Inicialización de miembros de datos estáticos
- 8. ¿Los miembros estáticos de una clase genérica son diferentes para diferentes tipos en Java?
- 9. En Java, ¿los miembros de la clase estáticos están compartidos entre los programas?
- 10. Definición de los miembros estáticos en C++
- 11. no estáticos miembros de datos Inicializadores preguntas
- 12. afirmativo estático para comprobar los miembros estáticos de datos de clase const?
- 13. ¿Cómo serializar una instancia de una clase que contiene miembros privados?
- 14. Recolección de basura de los miembros estáticos
- 15. Inicializando miembros estáticos de una clase con plantilla
- 16. ¿Cómo llamo a los miembros estáticos de una clase de plantilla?
- 17. ¿Los miembros estáticos ayudan a la eficiencia de la memoria?
- 18. ¿Cómo 'de-serializar' una clase derivada de datos serializados?
- 19. ¿Es posible recorrer los miembros de una clase en java?
- 20. Clase de plantilla C++ con miembros estáticos - Lo mismo para todos los tipos de la clase
- 21. Acceder a dejar los campos vinculados de los miembros estáticos
- 22. Forma Pythonic para Inicializar Miembros de Datos Estáticos (Complejos)
- 23. Niveles de acceso de los miembros de la clase java
- 24. ¿Utiliza una clase para almacenar datos estáticos en Java?
- 25. Herencia de miembros estáticos en C#
- 26. ¿Cómo acceder a los miembros estáticos de Global.asax?
- 27. La herencia de los miembros estáticos en PHP
- 28. Clase de miembros estáticos vs. interfaz normal tipo c
- 29. ¿Cómo y cuándo están dispuestos los miembros estáticos C#?
- 30. clase Singleton v/s con los miembros estáticos y métodos en Java
Detener el uso de los miembros estáticos de datos que deben ser serializados? – krosenvold
Adición: deje de usar miembros estáticos para mantener el estado mutable. – Juliet
+1, si serializa, no use miembros estáticos – marcgg