首页 > 编程语言 >Java transient关键字

Java transient关键字

时间:2023-04-21 11:35:33浏览次数:32  
标签:Java String 关键字 transient 线程 new password 变量


Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到主内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。   

  

Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。   

  

这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。   

  

而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。   

  

使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。   

  

由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。   

  

java关键字Transient   

  

翻译自http://www.devx.com/tips/Tip/13726。   

  

Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想   

用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。   

transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。  

注意static变量也是可以串行化的 

  

首先,让我们看一些Java serialization的代码:   

public class LoggingInfo implements java.io.Serializable   
{   
    private Date loggingDate = new Date();   
    private String uid;   
    private transient String pwd;   
      
    LoggingInfo(String user, String password)   
    {   
        uid = user;   
        pwd = password;   
    }   
    public String toString()   
    {   
        String password=null;   
        if(pwd == null)   
        {   
        password = "NOT SET";   
        }   
        else  
        {   
            password = pwd;   
        }   
        return "logon info: \n   " + "user: " + uid +   
            "\n   logging date : " + loggingDate.toString() +   
            "\n   password: " + password;   
    }   
}

  

现在我们创建一个这个类的实例,并且串行化(serialize)它 ,然后将这个串行化对象写如磁盘。   

  

LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");   
System.out.println(logInfo.toString());   
try  
{   
   ObjectOutputStream o = new ObjectOutputStream(   
                new FileOutputStream("logInfo.out"));   
   o.writeObject(logInfo);   
   o.close();   
}   
catch(Exception e) {//deal with exception}   
  
To read the object back, we can write   
  
try  
{   
   ObjectInputStream in =new ObjectInputStream(   
                new FileInputStream("logInfo.out"));   
   LoggingInfo logInfo = (LoggingInfo)in.readObject();   
   System.out.println(logInfo.toString());   
}   
catch(Exception e) {//deal with exception}

如果我们运行这段代码,我们会注意到从磁盘中读回(read——back (de-serializing))的对象打印password为"NOT SET"。这是当我们定义pwd域为transient时,所期望的正确结果。   

现在,让我们来看一下粗心对待transient域可能引起的潜在问题。假设我们修改了类定义,提供给transient域一个默认值,   

代码如下:   

public class GuestLoggingInfo implements java.io.Serializable   
{   
    private Date loggingDate = new Date();   
    private String uid;   
    private transient String pwd;   
      
    GuestLoggingInfo()   
    {   
        uid = "guest";   
        pwd = "guest";   
    }   
    public String toString()   
    {   
        //same as above   
     }   
}

现在,如果我们穿行化GuestLoggingInfo的一个实例,将它写入磁盘,并且再将它从磁盘中读出,我们仍然看到读回的对象打印password 为 "NOT SET"。当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数,   
而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。 

标签:Java,String,关键字,transient,线程,new,password,变量
From: https://blog.51cto.com/u_2198048/6212349

相关文章

  • 在Java代码中更优雅地调用Kotlin
    -Kotlin与Java良好的互操作性是其能够快速普及的原因之一。从Java虽然可以访问Kotlin,但是通过下面这些技巧可以让对Kotlin的访问变得更加友好和地道@JvmStaticKotlin中可以使用objectclass创建单例objectAnalytics{funinit(){...}funsend(event:Event){...}......
  • 推荐使用 Kotlin 关键字 Reified
    原文地址zhuanlan.zhihu.com推荐使用Kotlin关键字Reified残枫cps​目录收起1.不再需要传参数clazzreified方式2.不安全的转换reified方式3.不同的返回类型函数重载reified方式原文地址www.jianshu.comreified:使抽象的东西更加具体或真实,非常推荐Android开......
  • JAVA中的规则
    是看的尚硅谷的教材粘贴过来的,只是自己记录。如何看懂UML类图?没有好记性就多看几遍UML(UnifiedModelingLanguage,统一建模语言),用来描述软件模型和架的图形化语言。常用的UML工具软件有PowerDesinger、Rose和EnterpriseArchitect.UML工具软件不仅可以绘制软件开发中所......
  • 检查java的class文件版本
     packagetest;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.util.HashMap;importjava.util.Map;publicclassCheckClassVersion{publicstaticvoidmain(String[]......
  • java堆栈方法区
    原文地址zhuanlan.zhihu.comjava堆栈方法区残枫cps​目录收起栈区堆区方法区栈区栈区描述的是方法执行的内存模型。每个方法在执行时都会创建一个栈帧(存放存储局部变量、操作数栈、动态链接、方法出口等)JVM为每个线程创建一个栈,栈属于线程私有,不能实现线程间的共享!用......
  • JavaScript 测试及效验工具
    JavaScript是一款强大的广泛运用于现代Web站点及应用的脚本语言。作为一个技艺精湛的Web开发者,掌握JavaScript可以增强用户的使用体验,提供交互及富客户端等功能。尽管JavaScript的语法非常简单,但对于写程序而言仍然是困难重重,就是因为它的运行环境:基于Web浏览器。以下您可以看......
  • Java技术_基础技术(0003)_类执行顺序详解+实例(阿里面试题)+详细讲解+流程图
    一、总体原则列出执行顺序的原则(这里本人出了简化,比较明了。可能有漏的,请帮忙补充,但应付该实例足以):  ==父类先于子类;  ==静态先于非静态;  ==变量和块先于构造方法;  ==变量声明先于执行(变量赋值、块执行);(这一点是根据数据在内存中是如何存储的得出的,基本类型、对象、......
  • java调用python脚本,用到tensorflow、keras等第三方库
    https://blog.csdn.net/jstlovely/article/details/121247764?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168110434116800227452800%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=168110434116800227452800&......
  • 【Java基础】day16
    day16一、switch-case和if-else谁更快?switch-case在switch-case中,case的值是连续的话,会生成一个TableSwitch来进行优化,这样的情况下,只需要在表中进行判断即可。这里使用0-4的连续值来进行测试如果说多加几个Case的值,但是范围控制在比较小的范围时:这里使用0......
  • Java:谈谈线程池的使用?
    简介线程池是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来。核心参数1、核心线程数2、最大线程数3、空闲线程最大存活时间4、时间单位5、线程等待队列5、线程工厂......