Palabras clave transitorias de Java
1. La función y el método de uso de transitorio
Todos sabemos que mientras un objeto implementa la interfaz serilizable, el objeto se puede serializar. Este modelo de serialización de Java proporciona mucha conveniencia para los desarrolladores. No tenemos que relacionarnos con el proceso de serialización específico. Mientras esta clase implementa la interfaz serilizable, todas las propiedades y métodos de esta clase se serializarán automáticamente.
Sin embargo, en el proceso de desarrollo real, a menudo encontramos tales problemas. Algunas propiedades de esta clase deben ser serializadas, mientras que otras propiedades no necesitan ser serializadas. Por ejemplo, si un usuario tiene información confidencial (como contraseñas, números de tarjeta bancaria, etc.), por razones de seguridad, no desea transmitirse en operaciones de red (principalmente que implica operaciones de serialización, el caché de serialización local también es aplicable), y las variables correspondientes a esta información se pueden agregar con la palabra clave transitoria. En otras palabras, el ciclo de vida de este campo solo está en la memoria de la persona que llama y no se escribe en el disco para la persistencia.
En resumen, la palabra clave transitoria de Java nos proporciona conveniencia. Solo necesita implementar la interfaz serilizable y agregar la palabra clave transitorio antes de los atributos que no necesitan ser serializados. Al serializar el objeto, este atributo no se serializará al destino especificado.
El código de ejemplo es el siguiente:
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;/** * @description Use transient keywords to not serialize a Variable * Tenga en cuenta que al leer, el orden de los datos de lectura debe ser consistente con el orden de almacenar datos * * @author Alexia * @Date 2013-10-15 * http://www.manongjc.com/article/1609.html */public class Transiattest {public estático void main (string [] args) {usuario user usuario ();); user.setUsername ("Alexia"); user.setPasswd ("123456"); System.out.println ("Leer antes de serializable:"); System.out.println ("UserName:" + user.getUsername ()); System.err.println ("Password:" + user.getPasswd ()); Pruebe {ObjectOutputStream OS = New ObjectOutputStream (new FileOutputStream ("c: /user.txt")); OS.WriteObject (usuario); // Escribir el objeto de usuario en el archivo os.flush (); os.close (); } catch (FileNotFoundException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); } try {ObjectInputStream IS = New ObjectInputStream (new FileInputStream ("c: /user.txt")); user = (usuario) IS.ReadObject (); // leer los datos del usuario de la transmisión IS.Close (); System.out.println ("/nread después de serializable:"); System.out.println ("UserName:" + user.getUsername ()); System.err.println ("Password:" + user.getPasswd ()); } catch (FileNotFoundException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); } catch (ClassNotFoundException e) {E.PrintStackTrace (); }}} clase El usuario implementa serializable {private static final long SerialVersionUid = 8294180014912103005l; nombre de usuario de cadena privada; cadena transitoria privada pasada; public String getUsername () {return UserName; } public void setUsername (String UserName) {this.Username = username; } public String getPasswd () {return passwd; } public void setpasswd (string passwd) {this.passwd = passwd; }}La salida es:
Leer antes de serializable: Nombre de usuario: AlexiaPassword: 123456 Read After Serializable: Nombre de usuario: AlexiaPassword: NULL
El campo de contraseña es nulo, lo que significa que no se obtuvo información del archivo durante la deserialización.
2. Resumen de uso transitorio
1) Una vez que la variable se modifica por transitorio, la variable ya no será parte de la persistencia del objeto, y no se puede acceder al contenido de la variable después de la serialización.
2) La palabra clave transitoria solo puede modificar variables, pero no métodos y clases. Tenga en cuenta que las variables locales no pueden modificarse mediante palabras clave transitorias. Si una variable es una variable de clase definida por el usuario, la clase necesita implementar la interfaz Serializable.
3) Las variables modificadas por la palabra clave transitoria ya no se pueden serializar. Una variable estática no se puede serializar independientemente de si es modificada por transitorio.
El tercer punto puede ser confuso, porque descubrí que después de agregar la palabra clave estática al campo de nombre de usuario en la clase de usuario, el resultado de la ejecución del programa sigue sin cambios, es decir, el nombre de usuario del tipo estático también se lee como "alexia". ¿No es esto contradictorio con el tercer punto? En realidad, es así: el tercer punto es de hecho correcto (una variable estática no se puede serializar independientemente de si es modificado por transitorio). Después de la deserialización, el nombre de usuario de la variable estática en la clase es el valor de la variable estática correspondiente en el JVM actual. Este valor no se deriva de la deserialización en el JVM. ¿No lo crees? Ok, déjame probarlo a continuación:
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;/** * @description Use transient keywords to not serialize a Variable * Tenga en cuenta que al leer, el orden de los datos de lectura debe ser consistente con el orden de almacenar datos * * @author Alexia * @Date 2013-10-15 * http://www.manongjc.com */public class Transienttest {public static void main (string [] args) {user = new user ();; user.setUsername ("Alexia"); user.setPasswd ("123456"); System.out.println ("Leer antes de serializable:"); System.out.println ("UserName:" + user.getUsername ()); System.err.println ("Password:" + user.getPasswd ()); Pruebe {ObjectOutputStream OS = New ObjectOutputStream (new FileOutputStream ("c: /user.txt")); OS.WriteObject (usuario); // Escribir el objeto de usuario en el archivo os.flush (); os.close (); } catch (FileNotFoundException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); } try {// cambia el valor del nombre de usuario antes de la deserialización user.Username = "JMwang"; ObjectInputStream es = nuevo ObjectInputStream (nuevo FileInputStream ("C: /user.txt")); user = (usuario) IS.ReadObject (); // leer los datos del usuario de la transmisión IS.Close (); System.out.println ("/nread después de serializable:"); System.out.println ("UserName:" + user.getUsername ()); System.err.println ("Password:" + user.getPasswd ()); } catch (FileNotFoundException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); } catch (ClassNotFoundException e) {E.PrintStackTrace (); }}} clase El usuario implementa serializable {private static final long SerialVersionUid = 8294180014912103005l; Nombre de usuario de cadena estática pública; cadena transitoria privada pasada; public String getUsername () {return UserName; } public void setUsername (String UserName) {this.Username = username; } public String getPasswd () {return passwd; } public void setpasswd (string passwd) {this.passwd = passwd; }}El resultado de la operación es:
Leer antes de serializable: Nombre de usuario: AlexiaPassword: 123456 Read After Serializable: Nombre de usuario: JmwangPassword: NULL
Esto significa que el valor del nombre de usuario de la variable estática en la clase deserializada es el valor de la variable estática correspondiente en el JVM actual, que es el JMWANG modificado, no el valor Alexia durante la serialización.
3. Detalles de uso transitorio: ¿pueden ser serializadas realmente las variables modificadas por la palabra clave transitoria?
Piense en los siguientes ejemplos:
import java.io.externalizable; import java.io.file; import java.io.fileInputStream; import java.io.fileOutputStream; import java.io.ioException; import java.io.ObjectInputStream; import java.io.ObjectPutStream;/** * @Descripton Uso de Interface * * @ADESCRONTON * * @ACHATOR * * * @ATATA * * @ATATA * * @ATATA * * @ATATA * * @ATATA * * @AUTHAT * * @ATHATR * * * @ATATA * * @ATHATO * * @ATATA * * @@ACHATA * * @ATHATO * * @ATHATR. 2013-10-15 * */public class ExternalizableStest implementa externalizable {private Transient String Content = "Sí, me serializaré independientemente de si estoy modificado por la palabra clave transitoria o no"; @Override public void WriteExternal (ObjectOutput out) lanza IOException {out.writeObject (content); } @Override public void ReadExternal (ObjectInput in) lanza ioException, classNotFoundException {content = (String) in.readObject (); } public static void main (string [] args) lanza la excepción {externalizableTest et = new externalizableStest (); ObjectOutput out = new ObjectOutputStream (new FileOutputStream (nuevo archivo ("Test"))); out.writeObject (ET); ObjectInput in = new ObjectInputStream (new FileInputStream (nuevo archivo ("Test"))); et = (externalizableTest) in.readObject (); System.out.println (et.Content); out.close (); cercar(); }}¿La variable de contenido se serializa? Ok, he generado todas las respuestas, sí, el resultado es:
Sí, seré serializado, independientemente de si estoy modificado por la palabra clave transitoria o no
¿Por qué es esto? ¿No se dice que las variables de la clase no se serializarán después de ser modificadas por la palabra clave transitoria?
Sabemos que en Java, la serialización de objetos se puede implementar mediante la implementación de dos interfaces. Si se implementa la interfaz serializable, toda la serialización se realizará automáticamente. Si se implementa la interfaz externalizable, nada se puede serializar automáticamente. Debe especificar manualmente la variable que se serializa en el método WriteExternal, que no tiene nada que ver con si es modificado por Transitor. Por lo tanto, el segundo ejemplo genera el contenido inicializado por el contenido variable, no nulo.
Gracias por leer, espero que pueda ayudarte. ¡Gracias por su apoyo para este sitio!