que objeto libreria convertir java serialization final

java - objeto - serialversionuid generator



¿Cómo deserializa la serialización java los campos finales cuando no se especifica ningún constructor predeterminado? (3)

Tengo una clase que define un tipo de valor inmutable que ahora necesito serializar. La inmutabilidad proviene de los campos finales que se establecen en el constructor. Intenté serializar y funciona (¿sorprendentemente?), Pero no tengo idea de cómo.

Aquí hay un ejemplo de la clase

public class MyValueType implements Serializable { private final int value; private transient int derivedValue; public MyValueType(int value) { this.value = value; this.derivedValue = derivedValue(value); } // getters etc... }

Dado que la clase no tiene un constructor no arg, ¿cómo se puede instanciar y establecer el campo final?

(Aparte, noté esta clase particularmente porque IDEA no estaba generando una advertencia de inspección "no serialVersionUID" para esta clase, pero generó advertencias para otras clases que acabo de hacer serializable).


Dado que la clase no tiene un constructor no arg, ¿cómo se puede instanciar y establecer el campo final?

Se produce una desagradable magia negra. Hay una puerta trasera en la JVM que permite crear un objeto sin invocar ningún constructor. Los campos del nuevo objeto se inicializan primero a sus valores predeterminados (falso, 0, nulo, etc.) y luego el código de deserialización del objeto rellena los campos con los valores de la secuencia del objeto.

(Ahora que Java tiene un origen abierto, puedes leer el código que hace esto ... ¡y llorar!)


La JVM implementa la deserialización en un nivel por debajo de las construcciones de lenguaje básicas. Específicamente, no llama a ningún constructor.


Tanto Michael como Stephen le dieron una excelente respuesta, solo quiero advertirle sobre transient campos transient .

Si el valor predeterminado ( null para las referencias, 0 para las primitivas) no es aceptable para ellos después de la deserialización, entonces debe proporcionar su versión de readObject e inicializarla allí.

private void readObject ( final ObjectInputStream s ) throws ClassNotFoundException, IOException { s.defaultReadObject( ); // derivedValue is still 0 this.derivedValue = derivedValue( value ); }