最近,我在一个朋友的一个研究项目中遇到了十字架,他们正在学习Java编程的基础知识,一些忘记的敏感信息打印在文本文件中,并记住了Java中的瞬时关键字。
Java中的瞬时关键字在安全方面起着重要的作用,并且在上述类似的“事故”中非常有用,因为它将阻止敏感信息的传输,例如密码到文件,JSON消息等需要序列化的信息。
长话短说,如果将任何变量定义为瞬态, 除非将其定义为static或final ,否则它将不会序列化。
让我们来看一些例子。
在下面的示例中,我们将定义一些瞬态变量,我们将通过将它们写入文件,读取它们并查看影响来序列化它们。
import java.io.*;
public class TestTransient implements Serializable
{
// Normal variables
String a = "JCG";
String b = "IS";
// Transient variables
transient String c = "GREAT";
public static void main(String[] args) throws Exception
{
TestTransient foo = new TestTransient();
System.out.println("a before = " + foo.a);
System.out.println("b before = " + foo.b);
System.out.println("c before = " + foo.c);
System.out.println("---------------------");
// serialization
FileOutputStream fileOutputStream = new FileOutputStream("abc.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(foo);
// de-serialization
FileInputStream fileInputStream = new FileInputStream("abc.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
TestTransient output = (TestTransient) objectInputStream.readObject();
System.out.println("a from file = " + output.a);
System.out.println("b from file = " + output.b);
System.out.println("c from file = " + output.c);
}
}
输出为:
a before = JCG
b before = IS
c before = GREAT
-----------------------
a from file = JCG
b from file = IS
c from file = null
我们可以看到,标记为瞬态的变量c在序列化后丢失了其值。
让我们来看另一个例子。
import java.io.*;
public class TestTransient implements Serializable
{
// Normal variables
String a = "JCG";
String b = "IS";
// Transient variables
transient static String c = "GREAT";
transient final String d = "AGAIN!";
public static void main(String[] args) throws Exception
{
TestTransient foo = new TestTransient();
System.out.println("a before = " + foo.a);
System.out.println("b before = " + foo.b);
System.out.println("c before = " + foo.c);
System.out.println("d before = " + foo.d);
System.out.println("---------------------");
// serialization
FileOutputStream fileOutputStream = new FileOutputStream("abc.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(foo);
// de-serialization
FileInputStream fileInputStream = new FileInputStream("abc.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
TestTransient output = (TestTransient) objectInputStream.readObject();
System.out.println("a from file = " + output.a);
System.out.println("b from file = " + output.b);
System.out.println("c from file = " + output.c);
System.out.println("d from file = " + output.d);
}
}
输出为:
a before = JCG
b before = IS
c before = GREAT
d before = AGAIN!
------------------------
a from file = JCG
b from file = IS
c from file = GREAT
d from file = AGAIN!
那么这里发生了什么? 为什么同时打印c和d变量? 答案是因为它们两个都被标记为静态或最终的。
- 静态变量不是对象状态的一部分,因此暂态关键字无法应用。
- 最终变量已通过其值序列化,因此瞬态不再适用。
因此,下次记住此关键字时,您需要在序列化时有意放松的信息。
翻译自: https://www.javacodegeeks.com/2019/06/transient-keyword-in-java.html