1. 程式人生 > 實用技巧 >Java Transient 關鍵字小記

Java Transient 關鍵字小記

Transient

今天在看Java的AbstractList的原始碼,看到了transient關鍵字,很是好奇。因為在之前從來沒有看到了,也沒用到過。也沒見專案的程式碼庫裡有人用。
於是好奇的研究了一下。

引入時間

引入時間是在Java SE 7。
JLS:https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.3

有什麼作用

Variables may be marked transient to indicate that they are not part of the persistent state of an object.

變數可以被標示為transient,標示它不是物件持久化過程中的一部分

怎麼用

我有一個類

class UserInfo implements Serializable {

/   // 這個欄位標示為transient
    private transient int age;
    private String name;
    

    public UserInfo(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // getter 和setter
    // ....
}

搞個測試

@Test
void serializableTest() {
    final UserInfo test = new UserInfo("lisi", 23);
    assertEquals("lisi", test.getName());
    // 這裡age是23
    assertEquals(23, test.getAge());
    writeObjectToFile(test);
    UserInfo o = null;
    o = readToObject(o);
    assertEquals("lisi", o.getName());
    // 這裡age是0 也就是int的預設值,包裝型別的話是null
    assertEquals(0, o.getAge());
}
// 支撐方法
private void writeObjectToFile(UserInfo test) {
    try {
        ObjectOutputStream outputStream = new ObjectOutputStream(
            new FileOutputStream("./name.txt"));
        outputStream.writeObject(test);
        outputStream.flush();
        outputStream.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private UserInfo readToObject(UserInfo o) {
    try {
        ObjectInputStream inputStream = new ObjectInputStream(
            new FileInputStream("./name.txt"));
        o = (UserInfo) inputStream.readObject();
        inputStream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return o;
}

有個小坑: User類不能是內部類,一定要是一級類。

spring 的@transient的不同

Java Spring
關鍵字 註解
序列化時使用到 持久化資料到DB中用到
標記為序列化是忽略掉 標記為持久化是忽略掉

能在fasterxml.jackson 中生效嗎?

答案是

不能的

寫個測試驗證一下:

@Test
void jacksonTest() throws IOException {
    UserInfo test = new UserInfo("lisi", 23);
    assertEquals("lisi", test.getName());
    assertEquals(23, test.getAge());
    ObjectMapper mapper = new ObjectMapper();
    final String testJson = mapper.writeValueAsString(test);
    final UserInfo newUserInfo = mapper.readValue(testJson, UserInfo.class);
    assertEquals("lisi", newUserInfo.getName());
    assertEquals(23, newUserInfo.getAge());
}