• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Java中transient关键字的作用

技术杂谈 勤劳的小蚂蚁 3个月前 (01-25) 69次浏览 已收录 0个评论 扫描二维码
先解释下Java中的对象序列化
在讨论transient之前,有必要先搞清楚Java中序列化的含义;
Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,也可用于网络传输,一般当我们使用缓存cache(内存空间不够有可能会本地存储到硬盘)或远程调用rpc(网络传输)的时候,经常需要让我们的实体类实现Serializable接口,目的就是为了让其可序列化。
当然,序列化后的最终目的是为了反序列化,恢复成原先的Java对象,要不然序列化后干嘛呢,所以序列化后的字节序列都是可以恢复成Java对象的,这个过程就是反序列化。
关于transient关键字
Java中transient关键字的作用,简单地说,就是让某些被修饰的成员属性变量不被序列化,这一看好像很好理解,就是不被序列化,那么什么情况下,一个对象的某些字段不需要被序列化呢?如果有如下情况,可以考虑使用关键字transient修饰:
1、类中的字段值可以根据其它字段推导出来,如一个长方形类有三个属性:长度、宽度、面积(示例而已,一般不会这样设计),那么在序列化的时候,面积这个属性就没必要被序列化了;
2、其它,看具体业务需求吧,哪些字段不想被序列化;
PS,记得之前看HashMap源码的时候,发现有个字段是用transient修饰的,我觉得还是有道理的,确实没必要对这个modCount字段进行序列化,因为没有意义,modCount主要用于判断HashMap是否被修改(像put、remove操作的时候,modCount都会自增),对于这种变量,一开始可以为任何值,0当然也是可以(new出来、反序列化出来、或者克隆clone出来的时候都是为0的),没必要持久化其值。
  1. /**

  2. * The number of times this HashMap has been structurally modified

  3. * Structural modifications are those that change the number of mappings in

  4. * the HashMap or otherwise modify its internal structure (e.g.,

  5. * rehash).  This field is used to make iterators on Collection-views of

  6. * the HashMap fail-fast.  (See ConcurrentModificationException).

  7. */

  8. transient
    int
    modCount;

最后,为什么要不被序列化呢,主要是为了节省存储空间,其它的感觉没啥好处,可能还有坏处(有些字段可能需要重新计算,初始化什么的),总的来说,利大于弊。
举个例子
仅仅是示例,具体使用请根据实际情况:
  1. package com.ecej.esmart.workform.queue;
  2. import com.ecej.esmart.core.annotation.Log;
  3. import com.ecej.esmart.workform.dao.EsmartBaseDao;
  4. import com.ecej.nove.utils.common.BaseUtils;
  5. import org.apache.commons.lang.StringUtils;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  9. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  10. import org.springframework.stereotype.Component;
  11. import javax.annotation.Resource;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. /**
  16. * 删除周期订单虚拟档期表
  17. */
  18. @Component
  19. @RabbitListener(queues = "${esmart.del.cycle.order.schedule}")
  20. publicclassReceiverDelCycleOrderSchedule {
  21.    privatestaticfinalLogger LOGGER = LoggerFactory.getLogger(ReceiverDelCycleOrderSchedule.class);
  22.    @Resource
  23.    privateEsmartBaseDao esmartBaseDao;
  24.    @Log("删除周期订单虚拟档期表")
  25.    @RabbitHandler
  26.    publicvoid delCycleOrderSchedule(String parentOrderNo) {
  27.        try {
  28.            LOGGER.info("监听到的消息:{}", parentOrderNo);
  29.            if (StringUtils.isNotEmpty(parentOrderNo)) {
  30.                Map<String, Object> objectMap = newHashMap<>();
  31.                objectMap.put("parentOrderNo", parentOrderNo);
  32.                esmartBaseDao.delete(BaseUtils.makeClazzPath(com.ecej.esmart.workform.ecejservice.po.WorkOrderPo.class, "delCycleOrderSchedule"), objectMap);
  33.            }
  34.        } catch (Exception e) {
  35.            LOGGER.error(e.getMessage(), e);
  36.        }
  37.    }
  38. }
结果打印(达到目的,节省存储空间,成功恢复成原始对象):
1.原始对象
width : 3 height : 4 area : 12
2.反序列化后的对象
width : 3 height : 4 area : null
3.恢复成原始对象
width : 3 height : 4 area : 12
参考资料

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Java中transient关键字的作用
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00