【Java 基础三】transient关键字
最近在项目的开发过程中,涉及到了这么一个关键字-"transient",不知道大家有没有使用过,我这算是头一回吧!还是因为需求需要,在旁边的大牛的指引下巧妙的使用了一下。
1、transient的介绍及其作用
介绍
借用百度百科的话语:它属于java语言的关键字,变量修饰符,如果使用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是用transient关键字标记的成员变量不参与序列化过程。
作用
在项目开发的过程中,创建实体的时候我们都会习惯性的实现Serializable接口,一个对象只要实现了Serializable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利。但是在实际开发的过程中,我们也会遇到这样的尴尬:有个别属性我不想将去序列化,该如何解决?就比如在项目的使用过程中,银行卡号等一些保密的值,我只想让其使用一次即可。这时候,我们就可以使用transient关键字,避免了他在网络过程中进行传输。
2、什么是序列化及序列化的用途
什么是序列化
对象的寿命通常随着生成该对象的程序的终止而终止。但有些对象需要我们在需要的时候将该对象再恢复。对象通过写出自己状态的数值来记录自己,这个过程叫对象的序列化。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制的形式在网络上传输。把Java对象转换为子杰序列的过程称为对象的序列化;把自己列恢复为Java对象的过程称之为对象的反序列化。
两种用途
1)把对象的字节序列永久的保存到硬盘上,通常存放在一个文件中;
2)在网络上传送对象的字节序列;
其实不管是何种后台光甲,Hibernate也好,mybatis也好,并不要求持久化类必须实现java.io.Serializable接口,只是当这些后台框架在使用的过程中,已经采用了分布式结构的应用,当java对象在不同的进行节点之间传输时,这时候这个对象所属的类就必须要实现Serializable接口。
3、transient测试小结
- 一旦变量被transient修饰,变量将不再是对象持久化的一部分,打比方也就是说纵然我存放txt文件有值,但是再次读取的时候也会变为初始值;
- transient只能修饰变量,不能够修饰类和方法;
- 一个静态变量不管是否被transient修饰,均不能被序列化,特立独行的思想着实让人佩服;
具体实践见如下代码:
/**
* 创建的student类实现Serializable接口
*/
public class Student implements Serializable {
private static final long serialVersionUID = 8294180014912103005L;
// 静态变量加入transient关键字
private static transient String name;
// 性别加入transient关键字
private transient String sex;
// weight,idcard被transient
private String weight;
private transient int idCard = 1;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public int getIdCard() {
return idCard;
}
public void setIdCard(int idCard) {
this.idCard = idCard;
}
@Override
public String toString() {
return "Student{" + "name=" + name + ",sex=" + sex + ",weight=" + weight + ",idCard=" + idCard + '}';
}
}
class TransientTest {
public static void main(String[] args) {
// 创建实体
Student student = new Student();
// 实体赋值
student.setIdCard(12345678);
student.setName("huohuo");
student.setSex("girl");
student.setWeight("100");
System.out.println("before serialization:" + student);
try {
FileOutputStream fos = new FileOutputStream("d:/students.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(student); //将student对象写进文件
oos.flush();
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fis = new FileInputStream("d:/students.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Student student1 = (Student) ois.readObject();
fis.close();
System.out.println("after seriazliation:" + student1);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
}
最后执行效果:
before serialization:Student{name=huohuo,sex=girl,weight=100,idCard=12345678}
after seriazliation:Student{name=huohuo,sex=null,weight=100,idCard=0}
看执行结果,序列化前后的对比:name值无任何变化,如果在序列化之后再赋值,其name值也会随之变换而变换,随心所欲,特立独行的思想;sex和idcard值是transient修饰过的,所以对应的是输出的类型初始化的表示,string类型为null,int类型为0;weight序列化正常输出;