HashMap学习之transient

一. 首先贴一篇解释transient关键字的文章

What is transient keyword in Java?

What is Serialization?

If you want to understand what is transient, please learn about what is Serilization concept in Java if you are not familiar with that. Serialization is the process of making the object’s state is persistent. That means the state of the object is converted into stream of bytes and stored in a file. In the same way we can use the de-serilization concept to bring back the object’s state from bytes. This is one of the important concept in Java programming because this serialization is mostly used in the networking programming. The object’s which are needs to be transmitted through network has to be converted as bytes, for that purpose every class or interface must implement  serialization interface. It is a marker interface without any methods.

理解:首先需要了解一下什么事序列化,序列化就是将对象的状态进行持久化,它将对象的状态转换为字节流存储到一个文件当中,通过反序列化将字节文件重新转换为对象。序列化与反序列化主要用在网络变成当中。需要进行网络传输的对象都需要转换为字节文件,通过实现序列化接口来达到目的。序列化接口就是一个标记接口,他没有任何的方法。

What is Transient?

The keyword transient in Java used to indicate that the variable should not be serialized. By default all the variables in the object is converted to persistent state. In some cases, you may want to avoid persisting some variables because you don’t have the necessity to transfer across the network. So, you can declare those variables as transient. If the variable is declared as transient, then it will not be persisted. It is the main purpose of the transient keyword.

理解:默认情况下,对象中所有的变量都会转换为持久状态,但是有些情况变量在传输过程中是不需要进行持久化,这样你就可以将这些变量声明为transient变量。

Transient Keyword Example

package javabeat.samples;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class NameStore implements Serializable{
    private String firstName;
    private transient String middleName;
    private String lastName;
    public NameStore (String fName,
                         String mName,
                         String lName){
        this.firstName = fName;
        this.middleName = mName;
        this.lastName = lName;
    }
    public String toString(){
        StringBuffer sb = new StringBuffer(40);
        sb.append("First Name : ");
        sb.append(this.firstName);
        sb.append("Middle Name : ");
        sb.append(this.middleName);
        sb.append("Last Name : ");
        sb.append(this.lastName);
        return sb.toString();
    }
}
public class TransientExample{
    public static void main(String args[]) throws Exception {
        NameStore nameStore = new NameStore("Steve",
                                     "Middle","Jobs");
        ObjectOutputStream o = new ObjectOutputStream
                   (new FileOutputStream("nameStore"));
        // writing to object
        o.writeObject(nameStore);
        o.close();

        // reading from object
        ObjectInputStream in =new ObjectInputStream(
                new FileInputStream("nameStore"));
        NameStore nameStore1 = (NameStore)in.readObject();
        System.out.println(nameStore1);
    }
}
// output will be :
First Name : Steve
Middle Name : null
Last Name : Jobs

Look into the following example to understand the purpose of transient keyword:

In the above example, the variable middle Name is declared as  transient , so it will not be stored in the persistent storage. You can run the above example and check the results.
理解:上面的Middle name 域被声明为了transient变量,所以它就不会存储在持久存储空间中。
 
二. 下面说一下tranisient变量在hashmap中的应用,贴一下一个论坛中的帖子
HashMap中的table域是transient的,在序列化时候通过writeObject和readObject方法进行序列化与反序列化。writeObject通过写入buckets的个数以及大小,还有每个实体到ObjectOutputStream对象中来进行序列化。下面是writeObject的源码:
/**
  * Save the state of the <tt>HashMap</tt> instance to a stream (i.e.,
  * serialize it)
  *
  * @serialData The <i>capacity</i> of the HashMap (the length of the
  *             bucket array) is emitted (int), followed by the
  *             <i>size</i> (an int, the number of key-value
  *             mappings), followed by the key (Object) and value (Object)
  *             for each key-value mapping.  The key-value mappings are
  *             emitted in no particular order.
  */
      private void writeObject(java.io.ObjectOutputStream s)
             throws IOException
         {
             Iterator<Map.Entry<K,V>> i =
                 (size > 0) ? entrySet0().iterator() : null;

            // Write out the threshold, loadfactor, and any hidden stuff
            s.defaultWriteObject();

            // Write out number of buckets
            s.writeInt(table.length);

            // Write out size (number of Mappings)
            s.writeInt(size);

            // Write out keys and values (alternating)
            if (i != null) {
                while (i.hasNext()) {
                    Map.Entry<K,V> e = i.next();
                    s.writeObject(e.getKey());
                    s.writeObject(e.getValue());
                }
            }
        }

 三. 最后说一下为什么要将table域声明为transient

知乎上的一个回答最好理解,如下:

还有一个回答是国外网站上的,如下:

理解:主要原因是hashcode方法和JVM相关,在不同的操作平台有不同的实现。这样相同的键值在不同的平台计算出的哈希值有可能不一样。解决方法就是在序列话的时候将实体的内容进行持久化而不是table域,反序列化的时候再重新构建出HashMap对象。

 
贴一下引用的网址:
1.https://www.zhihu.com/question/38441152
2.http://supercoderz.in/understanding-transient-variables-in-java-and-how-they-are-practically-used-in-hashmap/
3.http://stackoverflow.com/questions/7103611/hashmap-serializability
4.http://stackoverflow.com/questions/9144472/why-is-the-hash-table-of-hashmap-marked-as-transient-although-the-class-is-seria
5.http://www.javabeat.net/what-is-transient-keyword-in-java/
 
 

转载于:https://www.cnblogs.com/Guoyutian/p/5184984.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值