虽是读书笔记,但是如转载请注明出处 http://segmentfault.com/blog/exploring/
.. 拒绝伸手复制党
一个问题:
在阅读HashMap
和TreeMap
的源码过程中,发现了一个奇怪的事情: 这些类执行了Serializable
接口,却在关键地方,比如hashmap将存储数据的table 数组声明为transient
. 这是何意?
stackoverflow 查了一下,大概有两个原因。
1.transient 是表明该数据不参与序列化。因为 HashMap 中的存储数据的数组数据成员中,数组还有很多的空间没有被使用,没有被使用到的空间被序列化没有意义。所以需要手动使用 writeObject() 方法,只序列化实际存储元素的数组。
2. 由于不同的虚拟机对于相同 hashCode 产生的 Code 值可能是不一样的,如果你使用默认的序列化,那么反序列化后,元素的位置和之前的是保持一致的,可是由于 hashCode 的值不一样了,那么定位函数 indexFor()返回的元素下标就会不同,这样不是我们所想要的结果.
Java对象序列化
对象 ----- 字节流 ----- 文件
什么是对象序列化:
Java 平台允许我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比 JVM 的生命周期更长。但在现实应用中,就可能要求在 JVM 停止运行之后能够保存 (持久化) 指定的对象,并在将来重新读取被保存的对象。Java 对象序列化就能够帮助我们实现该功能。
使用 Java 对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的 "状态",即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。
除了在持久化对象时会用到对象序列化之外,当使用 RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。
一个对象能够序列化的前提是实现`Serializable`接口, `Serializable` 接口没有方法,更像是个标记。有了这个标记的 Class 就能被序列化机制处理。使用 `ObjectInputStream` 和 `ObjectOutputStream` 进行对象的读写。
class User implements Serializable{
private static final long serialVersionUID = 201322060620L;
private String username;
private transient String passwd;
public String getUsername(){
return username;
}
public void setUsername(String username){
this.username = username;
}
public String getPasswd(){
return this.passwd;
}
public void setPasswd(String passwd){
this.passwd = passwd;
}
}
public class TransientTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
User user = new User();
user.setUsername("GSM");
user.setPasswd("1010");
System.out.println("read before Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
try{
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream("F:/user.txt"));
os.writeObject(user);//将User对象写入文件
os.flush();
os.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
try {
ObjectInputStream is = new ObjectInputStream(
new FileInputStream(
"F:/user.txt"));
user = (User) is.readObject(); // 从流中读取User的数据
is.close();
System.out.println("\nread after 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();
}
}
}
user.txt 即 user对象保存到文件的内容是二进制的串,16进制查看:
文件一共63B
想更一进步的支持我,请扫描下方的二维码,你懂的~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。