• Java高阶语法---transient


    背景:听说transient Java高阶语法是挺进BAT必经之路。

     

    transient

    Java中transient 关键字的作用,简单的说就是让某些被修饰的成员属性变量不被序列化。

    这又扯到了序列化和反序列化:

    Java中对象的序列化是指将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,也可以用网络传输;就比如我们使用缓存cache/redis或远程调用RPC(网络传输)如一些密码等不想让人看到的敏感信息的时候,都要让缓存或传输的实体类实现Serializable接口,就是为了序列化实体类。 反序列化:序列化后的终极目的还是反序列化,恢复原先的Java对象,So序列化后的总结序列都是可以恢复为java对象的,此恢复过程就称为反序列化。

    具体来说:

    1、transient修饰的变量将不再是对象持久化的一部分,此变量内容在序列化后无法获得;

    2、transient关键字只能修饰变量,本地变量除外,而不能修饰方法和类;

    3、transient修饰的变量不能再被序列化,除此之外静态变量有无transient修饰都不能被序列化;

    如下情况可以考虑使用transient关键字修饰:

    1、类中的某个字段可以根据其他的字段推导出来,如一个盈利类有三个属性(出售单价、进价、利润),那么在序列化的时候,利润这个属性就没必要序列化了;

    2、除此之外,具体看项目的业务需求,哪些字段不想被序列化则用transient 修饰即可;

    另外:不序列化还有一个好处,那就是节省内存空间。

    写个例子验证下:一个实体类读写流的操作,password用transient修饰,age用static修饰,userName常规操作,序列化实体类执行发现,password无法序列化,age结果值和反序列化之前不一致。

    FYI:

     1 import java.io.ByteArrayInputStream;
     2 import java.io.ByteArrayOutputStream;
     3 import java.io.ObjectInputStream;
     4 import java.io.ObjectOutputStream;
     5 import java.io.Serializable;
     6 import lombok.Data;
     7 import lombok.extern.slf4j.Slf4j;
     8 
     9 @Slf4j
    10 public class TestTransient {
    11     public static void main(String[] args) throws Exception {
    12         TestTransient.transientTest("tjt", "password666", 22);
    13     }
    14     public static void transientTest(String userName, String password,Integer age) throws Exception {
    15         Account account = new Account();
    16         account.setUserName(userName);
    17         account.setPassword(password);
    18         account.setAge(age);
    19         log.info("before serializeble result is:"+account.getUserName()+"-"+account.getPassword()+"-"+account.getAge());
    20         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    21         ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); 
    22         objectOutputStream.writeObject(account);
    23         byte[] bytes = byteArrayOutputStream.toByteArray(); // 将account 转为流
    24         account.age = 18;   // 在反序列化之前改变age值,结果:反序列化后的结果没有从序列化中取age值
    25         ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
    26         ObjectInputStream objectInputStream = null; 
    27         objectInputStream = new ObjectInputStream(byteArrayInputStream); 
    28         Account accountAfter = (Account) objectInputStream.readObject();  // 从流中获取account
    29         log.info("after serializeble result is:"+accountAfter.getUserName()+"-"+accountAfter.getPassword()+"-"+accountAfter.getAge());
    30     }
    31     @Data
    32     static class  Account implements Serializable {
    33         private static final long serialVersionUID = -8994113761711738784L;
    34         private String userName;
    35         private transient String password;
    36         private static Integer age;
    37         public static Integer getAge() {
    38             return age;
    39         }
    40         public static void setAge(Integer age) {
    41             Account.age = age;
    42         }
    43     }
    44 }

    执行结果:

    - before serializeble result is:tjt-password666-22
    - after serializeble result is:tjt-null-18

  • 相关阅读:
    Android Studio no debuggable applications解决方案2
    Android CountDownTimer倒计时器的使用
    git 创建分支并切换
    com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: current time:
    为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment
    Android 使WebView支持HTML5 Video(全屏)播放的方法
    使用retrofit注意
    解决 Android Studio 乱码问题
    Android视觉规范-间距规范与文字规范单位换算(dip、sp与px)
    教你如何删除WIN7系统文件以及无法删除的文件
  • 原文地址:https://www.cnblogs.com/taojietaoge/p/10260145.html
Copyright © 2020-2023  润新知