广告
返回顶部
首页 > 资讯 > 精选 >Java中 transient关键字怎么使用
  • 750
分享到

Java中 transient关键字怎么使用

2023-06-19 10:06:45 750人浏览 薄情痞子
摘要

本篇文章为大家展示了Java中 transient关键字怎么使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1. transient的作用及使用方法我们都知道一个对象只要实现了Serilizabl

本篇文章为大家展示了Java中 transient关键字怎么使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

1. transient的作用及使用方法

我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。

然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。

总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

示例code如下:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class TransientTest {

    

    public static void main(String[] args) {

        

        User user = new User();

        user.setUsername("Alexia");

        user.setPasswd("123456");

        

        System.out.println("read before Serializable: ");

        System.out.println("username: " + user.getUsername());

        System.err.println("passWord: " + user.getPasswd());

        

        try {

            ObjectOutputStream os = new ObjectOutputStream(

                    new FileOutputStream("C:/user.txt"));

            os.writeObject(user); // 将User对象写进文件

            os.flush();

            os.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        try {

            ObjectInputStream is = new ObjectInputStream(new FileInputStream(

                    "C:/user.txt"));

            user = (User) is.readObject(); // 从流中读取User的数据

            is.close();

            

            System.out.println("read after Serializable: ");

            System.out.println("username: " + user.getUsername());

            System.err.println("password: " + user.getPasswd());

            

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

}

class User implements Serializable {

    private static final long serialVersionUID = 8294180014912103005L;  

    

    private String username;

    private transient String passwd;

    

    public String getUsername() {

        return username;

    }

    

    public void setUsername(String username) {

        this.username = username;

    }

    

    public String getPasswd() {

        return passwd;

    }

    

    public void setPasswd(String passwd) {

        this.passwd = passwd;

    }

}

输出为:

read before Serializable: 

username: Alexia

password: 123456

read after Serializable: 

username: Alexia

password: null

密码字段为null,说明反序列化时根本没有从文件中获取到信息。

2. transient使用小结

1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

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

第三点可能有些人很迷惑,因为发现在User类中的username字段前加上static关键字后,程序运行结果依然不变,即static类型的username也读出来为“Alexia”了,这不与第三点说的矛盾吗?实际上是这样的:第三点确实没错(一个静态变量不管是否被transient修饰,均不能被序列化),反序列化后类中static型变量username的值为当前JVM中对应static变量的值,这个值是JVM中的不是反序列化得出的,不相信?好吧,下面我来证明:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class TransientTest {

    

    public static void main(String[] args) {

        

        User user = new User();

        user.setUsername("Alexia");

        user.setPasswd("123456");

        

        System.out.println("read before Serializable: ");

        System.out.println("username: " + user.getUsername());

        System.err.println("password: " + user.getPasswd());

        

        try {

            ObjectOutputStream os = new ObjectOutputStream(

                    new FileOutputStream("C:/user.txt"));

            os.writeObject(user); // 将User对象写进文件

            os.flush();

            os.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

        try {

            // 在反序列化之前改变username的值

            User.username = "jmwang";

            

            ObjectInputStream is = new ObjectInputStream(new FileInputStream(

                    "C:/user.txt"));

            user = (User) is.readObject(); // 从流中读取User的数据

            is.close();

            

            System.out.println("read after Serializable: ");

            System.out.println("username: " + user.getUsername());

            System.err.println("password: " + user.getPasswd());

            

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

}

class User implements Serializable {

    private static final long serialVersionUID = 8294180014912103005L;  

    

    public static String username;

    private transient String passwd;

    

    public String getUsername() {

        return username;

    }

    

    public void setUsername(String username) {

        this.username = username;

    }

    

    public String getPasswd() {

        return passwd;

    }

    

    public void setPasswd(String passwd) {

        this.passwd = passwd;

    }

}

运行结果为:

read before Serializable: 

username: Alexia

password: 123456

read after Serializable: 

username: jmwang

password: null

这说明反序列化后类中static型变量username的值为当前JVM中对应static变量的值,为修改后jmwang,而不是序列化时的值Alexia。

3. transient使用细节——被transient关键字修饰的变量真的不能被序列化吗?

思考下面的例子:

import java.io.Externalizable;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInput;

import java.io.ObjectInputStream;

import java.io.ObjectOutput;

import java.io.ObjectOutputStream;

public class ExternalizableTest implements Externalizable {

    private transient String content = "是的,我将会被序列化,不管我是否被transient关键字修饰";

    @Override

    public void writeExternal(ObjectOutput out) throws IOException {

        out.writeObject(content);

    }

    @Override

    public void readExternal(ObjectInput in) throws IOException,

            ClassNotFoundException {

        content = (String) in.readObject();

    }

    public static void main(String[] args) throws Exception {

        

        ExternalizableTest et = new ExternalizableTest();

        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(

                new File("test")));

        out.writeObject(et);

        ObjectInput in = new ObjectInputStream(new FileInputStream(new File(

                "test")));

        et = (ExternalizableTest) in.readObject();

        System.out.println(et.content);

        out.close();

        in.close();

    }

}

content变量会被序列化吗?好吧,我把答案都输出来了,是的,运行结果就是:

是的,我将会被序列化,不管我是否被transient关键字修饰

这是为什么呢,不是说类的变量被transient关键字修饰以后将不能序列化了吗?

我们知道在Java中,对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。因此第二个例子输出的是变量content初始化的内容,而不是null。

上述内容就是Java中 transient关键字怎么使用,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网精选频道。

--结束END--

本文标题: Java中 transient关键字怎么使用

本文链接: https://www.lsjlt.com/news/295643.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中 transient关键字怎么使用
    本篇文章为大家展示了Java中 transient关键字怎么使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1. transient的作用及使用方法我们都知道一个对象只要实现了Serilizabl...
    99+
    2023-06-19
  • Java中transient关键字怎么使用
    本篇内容主要讲解“Java中transient关键字怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中transient关键字怎么使用”吧!一、概要介绍   对...
    99+
    2023-07-06
  • 详解java中的transient关键字
    说实话学了一段时间java的朋友对于transient这个关键字依旧很陌生基本没怎么用过,但是transient关键字在java中却起到了不可或缺的地位!如果要说讲到,我觉得最可能出现的地方是IO流中对象流(也叫序列化流)的时候会讲到!相信...
    99+
    2019-12-18
    java transient
  • java中的transient关键字有什么作用
    作用:体现在将数据序列化的时候,你不想把其中的某个属性序列化到文件中,就需要用transient修饰,指明该属性是一个临时的属性相关java视频教程:java免费视频教程这是一个学生类:public class Student implem...
    99+
    2017-01-06
    java入门 java transient 关键字 作用
  • Java中transient关键字的详细总结
    目录一、概要介绍   1. 序列化2. 为什么要用transient关键字?3. transient的作用二、transient使用总结三、使用场景一、概要介绍&...
    99+
    2023-05-15
    Java transient关键字 transient关键字 Java transient
  • 被遗忘的Java关键字transient的使用详解
    目录前言transient 是什么简单示例使用场景序列化敏感数据提高序列化性能临时数据需要注意的点总结前言 今天在看项目代码时候,看到了下面这样一行代码,用transient修饰了一...
    99+
    2023-05-17
    Java关键字transient使用 Java关键字transient Java transient
  • java中abstract关键字怎么使用
    在Java中,abstract关键字主要用于定义抽象类和抽象方法。1. 抽象类的定义:使用abstract关键字修饰类,将其声明为抽...
    99+
    2023-09-23
    java
  • Java中super关键字怎么使用
    这篇文章主要讲解了“Java中super关键字怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中super关键字怎么使用”吧!supersuper是一个关键字,全部小写。sup...
    99+
    2023-07-02
  • java中this关键字怎么使用
    这篇文章主要介绍了java中this关键字怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java中this关键字怎么使用文章都会有所收获,下面我们一起来看看吧。this 的使用:修饰属性和方法,也可以理...
    99+
    2023-06-26
  • java final关键字怎么使用
    这篇文章主要介绍“java final关键字怎么使用”,在日常操作中,相信很多人在java final关键字怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java final关键字怎么使用”的疑惑有所...
    99+
    2023-07-04
  • java instance关键字怎么使用
    在Java中,关键字"instance"用于判断一个对象是否属于特定的类或其子类的实例。它用于实现类型检查和类型转换。以下是"ins...
    99+
    2023-10-20
    java
  • Java super关键字怎么使用
    本文小编为大家详细介绍“Java super关键字怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java super关键字怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.s...
    99+
    2023-07-02
  • java中的final关键字怎么使用
    在Java中,final关键字可以用于修饰类、方法和变量。1. final修饰类:final修饰的类是不可被继承的,即该类不能有子类...
    99+
    2023-08-24
    java final
  • java中的volatile关键字怎么使用
    本篇内容介绍了“java中的volatile关键字怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.volatile实现可见性的原理...
    99+
    2023-06-25
  • java中的super关键字怎么使用
    在Java中,super是一个关键字,用于引用父类的成员变量、成员方法和构造方法。1. 引用父类的成员变量:可以使用super关键字...
    99+
    2023-08-08
    java super
  • Java中super关键字怎么用
    本篇内容介绍了“Java中super关键字怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!super有什么用?(1)当子类中构造方法第一...
    99+
    2023-06-29
  • Java中Native关键字怎么用
    这篇文章将为大家详细讲解有关Java中Native关键字怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、Java中Native关键字的语法本机代码的语法与普通函数定义相同,在函数开头添加了“nat...
    99+
    2023-06-22
  • Java的关键字abstract怎么使用
    本文小编为大家详细介绍“Java的关键字abstract怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java的关键字abstract怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. 理解ab...
    99+
    2023-06-30
  • Java的abstract关键字怎么使用
    在Java中,abstract关键字可以用于以下三个地方:1. 抽象类:使用abstract关键字来声明一个抽象类。抽象类是不能被实...
    99+
    2023-09-22
    java abstract
  • Java的Instanceof关键字怎么使用
    今天小编给大家分享一下Java的Instanceof关键字怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。举例:cla...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作