transient, 译作“短暂的,临时的”,他是 java 关键字之一,只能修饰变量,被修饰的实例变量,在对象存储时,它将不再需要维持。
示例
这里,我们可以简单地理解为,对一个对象的变量做临时处理,使其只能存在于内存中,而对对象进行文件的读写,或者网络传输时,被修饰的属性的值为 null。
下面,结合实例分析一下:
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
class User implements Serializable { private static final long serialVersionUID = 1L;
private String username; private String password;
public User() { }
public User(String username, String password) { super(); this.username = username; this.password = password; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
@Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } }
|
User1.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
public class User1 implements Serializable {
private static final long serialVersionUID = 1L;
private String username; private transient String password;
public User1() { super(); }
public User1(String username, String password) { super(); this.username = username; this.password = password; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
@Override public String toString() { return "User1 [username=" + username + ", password=" + password + "]"; }
}
|
之后,我们执行下面的 Main 主函数
1 2 3 4 5 6 7 8 9 10 11 12
| public class Main { public static void main(String[] args) { String username = "admin"; String password = "123456";
User user = new User(username, password); User1 user1 = new User1(username, password);
System.out.println(user.toString()); System.out.println(user1.toString()); } }
|
但是输出的结果却是:
User1 还是把 password 输出了,这是因为当前的User, User1的对象都没有进行序列化,所以就没有反序列化啦,这个关键字当然也就没有什么用了,
那好,我们就试着模拟一下对象的序列化(文件的读写操作)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public class FileIO {
File file;
public FileIO(String filepath) { file = new File(filepath); if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }
public void write(Serializable user) { try { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); out.writeObject(user); out.flush(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public String read() { String result = null; try { ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); Object obj = in.readObject(); result = obj.toString(); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return result; } }
|
接下来我们再对 Main 主函数进行修改:
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) { FileIO io = new FileIO("D:/transient.txt"); io.write(user); System.out.println(io.read()); io.write(user1); System.out.println(io.read()); } }
|
这时候,密码已经成为了 null
.
总结
- 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
- transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
- 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。