为了账号安全,请及时绑定邮箱和手机立即绑定

Java中HashMap关键字transient的疑惑

Java中HashMap关键字transient的疑惑

桃花长相依 2019-03-30 09:34:03
HashMap中有个对象transientEntry[]table;这个是存储数据的地方,但是为什么要加上关键字transient呢对于transient的解释transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,也就是说没法持久化。那么这种设计为什么用在HashMap中呢?有什么用意
查看完整描述

2 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

好问题.原因当然如@Windoze所言,有效率的考虑,但还有更深的原因.
EffectiveJava2nd,Item75,Joshua大神提到:
Forexample,considerthecaseofahashtable.Thephysical
representationisasequenceofhashbucketscontainingkey-value
entries.Thebucketthatanentryresidesinisafunctionofthehash
codeofitskey,whichisnot,ingeneral,guaranteedtobethesame
fromJVMimplementationtoJVMimplementation.Infact,itisn'teven
guaranteedtobethesamefromruntorun.Therefore,acceptingthedefaultserializedformforahashtablewouldconstituteaseriousbug.Serializinganddeserializingthehashtablecouldyieldan
objectwhoseinvariantswereseriouslycorrupt.
怎么理解?看一下HashMap.get()/put()知道,读写Map是根据Object.hashcode()来确定从哪个bucket读/写.而Object.hashcode()是native方法,不同的JVM里可能是不一样的.
打个比方说,向HashMap存一个entry,key为字符串"STRING",在第一个java程序里,"STRING"的hashcode()为1,存入第1号bucket;在第二个java程序里,"STRING"的hashcode()有可能就是2,存入第2号bucket.如果用默认的串行化(Entry[]table不用transient),那么这个HashMap从第一个java程序里通过串行化导入第二个java程序后,其内存分布是一样的.这就不对了.HashMap现在的readObject和writeObject是把内容输出/输入,把HashMap重新生成出来.
                            
查看完整回答
反对 回复 2019-03-30
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

首先你要明白,一个HashMap从功能上来说就是一个Map。所谓Map,就是存放Key/Value的数据结构,所以,任何一个Map类的数据结构,从逻辑上说只包含key和value,其它所有的东西都只是辅助而已。
所以HashMap自己实现了readObject和writeObject,在其中它保存了bucketsize,entrycount(这两个其实不是必需的,但有助于提高效率)和所有的key/value(这个才是必须的)。
PS.如果我没记错,其实它还调用了defaultReadObject/defaultWriteObject读写了loadfactor、threshold之类的其它一些东东。
                            
查看完整回答
反对 回复 2019-03-30
  • 2 回答
  • 0 关注
  • 484 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信