关于JAVA中的transient关键字 静态变量

刚才在学习 HashMap 源码的过程中,发现了一个transient 关键字,发现自己不熟悉,然后也又开始了挖掘。


一.transient 的使用总结

1、transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。

2、被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。

3、一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量一样被初始化。

二.transient 有什么作用?

发现transient 可以让jvm不对某些变量进行序列化,使得在反序列的过程中获取不到改变量。(听着好像感觉没有用处,但实际应用确实还是会用到以及在面试时也会问到。)

实际用到的地方:譬如 InputStream 这个类没有实现Serializable接口的,但要对拥有InputStream  变量的类进行序列化的时候,便会出现java.io.NotSerializableException 。此时我们就需要使用 transient 修饰 InputStream  变量。

三.代码示例:

第一个类:

import java.io.Serializable;

public class ClassLib implements Serializable {

    private transient InputStream is;
    private int majorVer;
    private int minorVer;
    private transient static  Integer ainte;
    private transient static  Integer astatint=3;

    ClassLib(InputStream is) throws IOException {
        System.out.println("ClassLib(InputStream) called");
        this.is = is;
        DataInputStream dis;
        ainte=1;
        if (is instanceof DataInputStream)
            dis = (DataInputStream) is;
        else
            dis = new DataInputStream(is);
        if (dis.readInt() != 0xcafebabe)
            throw new IOException("not a .class file");
        minorVer = dis.readShort();
        majorVer = dis.readShort();
    }

    int getMajorVer() {
        return majorVer;
    }

    int getMinorVer() {
        return minorVer;
    }

    void showIS() {
        System.out.println(is);
    }

    public Integer getAinte() {
        return ainte;
    }

    public void setAinte(Integer ainte) {
        this.ainte = ainte;
    }



    public static int getAstatint() {
        return astatint;
    }

    public static void setAstatint(int astatint) {
        ClassLib.astatint = astatint;
    }
}
第二个类:

import java.io.*;

public class TransDemo {
    public static void main(String[] args) throws IOException {
        ClassLib cl = new ClassLib(new FileInputStream("C:\\Users\\Administrator\\Desktop\\HelloDate.class"));//此处参数指定为一个class文件
        System.out.printf("Minor version number: %d%n", cl.getMinorVer());
        System.out.printf("Major version number: %d%n", cl.getMajorVer());
        System.out.printf("getAinte  : %d%n", cl.getAinte());
        System.out.printf("getAstatint  : %d%n", cl.getAstatint());
        cl.showIS();

        try (FileOutputStream fos = new FileOutputStream("x.ser");
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(cl);
        }

        cl = null;

        try (FileInputStream fis = new FileInputStream("x.ser");
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            System.out.println();
            cl = (ClassLib) ois.readObject();
            System.out.printf("Minor version number: %d%n", cl.getMinorVer());
            System.out.printf("Major version number: %d%n", cl.getMajorVer());
            System.out.printf("getAinte  : %d%n", cl.getAinte());
            System.out.printf("getAstatint  : %d%n", cl.getAstatint());
            cl.showIS();
        } catch (ClassNotFoundException cnfe) {
            System.err.println(cnfe.getMessage());
        }
    }

}

运行结果:

ClassLib(InputStream) called
Minor version number: 0
Major version number: 52
getAinte  : 1
getAstatint  : 3
java.io.FileInputStream@12a3a380


Minor version number: 0
Major version number: 52
getAinte  : 1
getAstatint  : 3
null


分析:对第一个类进行了序列化,和序列化操作。

Minor 和 Major 在反序列化后都有数值是因为,其被正常序列化。

 Ainte和Astatint是有由于静态变量的关系(静态变量一次初始化赋值,之后该类的对象的此变量均会有相同数值,与序列化无关)

Is不出现异常和现实Null数值,体现了transient不让其序列化的作用。

四.附加内容(关于静态变量的补充)

1.只在类第一次使用时加载时进行初始化  表明第一次用就要初始化,后面根据需要是可以再次赋值。(有需要就赋值)
2.公共性,就是说,一个类的静态成员,它是属于大伙的,所有的类对象共享的,不像成员变量是自己的。


代码示例:

第一个类:

public class TestStatic {
    private static  Integer i;

    public TestStatic(Integer w) {
        this.i=w;
    }

    public TestStatic() {
    }

    public static Integer getI() {
        return i;
    }

    public static void setI(Integer i) {
        TestStatic.i = i;
    }
}
第二个类:

public class Test {

    public static void main(String[] args) {

        TestStatic te=new TestStatic(2);

        System.out.println(te.getI());


        TestStatic te2=new TestStatic();

        System.out.println(te.getI());



    }


}
分析:发现第二个te2 对象有i数值的时候,大家一定能明白静态变量的含义了。

各位老铁,有错误一定要提出来哟,大家一起学习。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值