Java中的transient关键字

2023-11-14

前言
说实话学了一段时间java的朋友对于transient这个关键字依旧很陌生基本没怎么用过,但是transient关键字在java中却起到了不可或缺的地位!如果要说讲到,我觉得最可能出现的地方是IO流中对象流(也叫序列化流)的时候会讲到!

在学习java的过程中transient关键字少见的原因其实离不开它的作用:transient关键字的主要作用就是让某些被transient关键字修饰的成员属性变量不被序列化。实际上也正是因此,在学习过程中很少用得上序列化操作,一般都是在实际开发中!

Java中的关键字如下表格:

关键字列表
访问控制 private protected public
类方法变量修饰符 abstract class extends final implements interface native new static
strictfp synchronized transient volatile
程序控制 break continue return do while if else for instanceof
switch case default
错误处理 try catch throw throws
包相关 import package
基本类型 boolean byte char double float int long short
TRUE FALSE
变量引用 super this void
保留字 goto const

 注:表中true、false严格来讲不是关键字

每个关键字的含义:

关键字含义
private 一种访问控制方式:私有模式
protected 一种访问控制方式:保护模式
public 一种访问控制方式:共用模式
abstract 表明类或者成员方法具有抽象属性
class
extends (继承)表明一个类型是另一个类型的子类型,这里常见的类型有类和接口
final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变
implements 表明一个类实现了给定的接口
interface 接口
native 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的
new 用来创建新实例对象
static 表示具有静态属性
strictfp 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
synchronized 表明一段代码需要同步执行
transient 声明不用序列化的成员域
volatile 表明两个或者多个变量必须同步地发生变化
break 提前跳出一个块
continue 回到一个块的开始处
return 从成员方法中返回数据
while 用在循环结构中
if 条件语句的引导词
else 用在条件语句中,表明当条件不成立时的分支
for 一种循环结构的引导词
instanceof 用来测试一个对象是否是指定类型的实例对象
switch 分支结构语句的引导词
case 用在switch语句之中,表示其中的一个分支
default 默认,例如,用在switch语句中,表明一个默认的分支,可写可不写,但为了保证代码的规范性和健壮性,建议加上,更易看懂代码。
try 尝试一个可能抛出异常的程序块
catch 用来异常处理时,捕捉异常
throw 抛出一个异常
throws 声明在当前定义的成员方法中所有需要抛出的异常
import 表明要访问指定的类或包
package
boolean 基本数据类型之一,布尔类型
byte 基本数据类型之一,字节类型
char 基本数据类型之一,字符类型
double 基本数据类型之一,双精度浮点数类型
float 基本数据类型之一,单精度浮点数类型
int 基本数据类型之一,整数类型
long 基本数据类型之一,长整型类型
short 基本数据类型之一,短整型类型
super 表明当前对象的父类型的引用或父类型的构造方法
this 指向当前实例对象的引用
void 声明当前成员方法没有返回值
goto 保留关键字,没有具体含义
const 保留关键字,没有具体含义

提到这里,讲一讲Java中的访问控制修饰符public/protected/friendly/private

1.public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用

2.private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。

3.protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。

作用域 当前类 同一package 子孙类 其它package
public
protected ×
friendly × ×
private × × ×

注:不写时默认为friendly

目录

1、何谓序列化和反序列化?

2.为何要序列化?

3、 序列化与transient的使用

3.1、没有实现Serializable接口进行序列化情况

3.2、实现Serializable接口序列化情况

3.3、普通序列化情况

3.4、属性加上transient序列化情况

4、transient关键字小结


1、何谓序列化和反序列化?

说起序列化,随之而来的另一个概念就是反序列化,记住了序列化就相当于记住了反序列化,因为反序列化就是序列化反过来。

专业术语定义的序列化和反序列化:

“序列化”是一种把对象的状态转化成字节流的机制,“反序列化”是其相反的过程,把序列化成的字节流用来在内存中重新创建一个实际的Java对象。这个机制被用来“持久化”对象。通过对象序列化,可以方便的实现对象的持久化储存以及在网络上的传输。

 对象被转换成“字节流”后可以存入文件,内存,亦或者是数据库内进行持久化保存。然后通过“反序列化”可以把“字节流”转换成实际的Java对象。

对象的序列化是与平台无关的,因此在一个平台上被“序列化”的对象可以很容易的在另一个不相同的平台上给“反序列化”出来。

图理解序列化和反序列化:

koko

 

2.为何要序列化?

Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写道数据库或文件中,也可以用于网络传输,一般当我们使用缓存cache(内存空间不够有可能会本地存储到硬盘)或者远程调用rpc(网络传输)的时候,经常需要让我们的实体类实现Serializable接口,目的就是为了让其可序列化。

 

  • 在开发过程中要使用transient关键字修饰的例子:

如果一个用户有一些密码等信息,为了安全起见,不希望在网络操作中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写道磁盘里持久化。

 

  • 在开发过程中不需要transient关键字修饰的例子:

1、类中的字段值可以根据其它字段推导出来。

2、看具体业务需求,哪些字段不想被序列化。

 

  •  为什么要不被序列化呢?

其实主要是为了节省存储空间。优化程序!被序列化的字段或数据会保存在磁盘中从而造成存储资源空间浪费,上面也提到过,通过对象序列化,可以方便的实现对象的持久化储存以及在网络上的传输。

当然,序列化后的最终目的是为了反序列化,恢复成原先的Java对象,要不然序列化后干嘛呢,就像买菜一样,用塑料袋包裹最后还是为了方便安全到家再去掉塑料袋,所以序列化后的字节序列都是可以恢复成Java对象的,这个过程就是反序列化。

 

3、 序列化与transient的使用

1、需要做序列化的对象的类,必须实现序列化接口:Java.lang.Serializable接口(一个标志接口,没有任何抽象方法),Java中大多数类都实现了该接口,比如:StringInteger类等,不实现此接口的类将不会使任何状态序列化或反序列化,否则会抛出NotSerializableException异常。

2、底层会判断,如果当前对象是Serializable的实例,才允许做序列化,Java对象instanceof Serializable来判断。

3、在Java中使用对象流ObjectOutputStream来完成序列化以及ObjectInputStream流反序列化

1.ObjectOutputStream:通过writeObject()方法做序列化操作

2.ObjectInputStream:通过readObject()方法做反序列化操作

4、该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient关键字修饰。

IO流的主要分类:

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串 / / StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流 / / InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream / /
抽象基类 FilterInputStream FilterOutputStream FilterReader FilterWriter
打印类 / PrintStream / PrintWriter
推回输入流 PushbackInputStream / PushbackReader /
特殊流 DataInputStream DataOutputStream / /
注:倾斜 + 下划线代表抽象类,无法创建实例。红色表示节点流,必须直接与指定的物理节点关联

3.1、没有实现Serializable接口进行序列化情况

package com.krt.business.controller;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

class UserInfo{   //没有实现Serializable接口
    private String name;
    private transient String password;

    public UserInfo(String name,String pwd){
        this.name = name;
        this.password = pwd;
    }

    @Override
    public String toString(){
        return "UserInfo{"+"name='"+ name + '\'' + ",password='" + password + '\'' +'}';
    }
}

public class TransientDemo {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo("张三","123456");
        System.out.println("序列化之前信息:"+userInfo);
        try{
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\1122.txt"));
            output.writeObject(userInfo);
            output.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

运行结果:

 

3.2、实现Serializable接口序列化情况

当我们加上实现Serializable接口再运行会发现,文件1122.txt内容是这样的,说明成功写入了。

 

3.3、普通序列化情况

package com.krt.business.controller;

import java.io.*;

//第一步实现Serializable接口
class UserInfo implements Serializable {

    private String name;

    //定义普通成员属性,没有加序列化transient关键字
    private String password;

    public UserInfo(String name,String pwd){
        this.name = name;
        this.password = pwd;
    }

    @Override
    public String toString(){
        return "UserInfo{"+"name='"+ name + '\'' + ",password='" + password + '\'' +'}';
    }
}

public class TransientDemo {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo("张三","123456");
        System.out.println("序列化之前信息:"+userInfo);
        try{
            //第二步开始序列化操作
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\1122.txt"));
            output.writeObject(userInfo);
            output.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        try{
            //第三步开始反序列化操作
            ObjectInputStream input = new ObjectInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\1122.txt"));
            //ObjectInputStream的readObject方法会抛出类找不到(ClassNotFoundException)异常
            Object o = input.readObject();
            System.out.println("反序列化之后信息:"+o);
        }catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

 

3.4、属性加上transient序列化情况

package com.krt.business.controller;

import java.io.*;

//第一步实现Serializable接口
class UserInfo implements Serializable {

    private String name;

    //定义成员属性,属性加上序列化transient关键字
    private transient String password;

    public UserInfo(String name,String pwd){
        this.name = name;
        this.password = pwd;
    }

    @Override
    public String toString(){
        return "UserInfo{"+"name='"+ name + '\'' + ",password='" + password + '\'' +'}';
    }
}

public class TransientDemo {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo("张三","123456");
        System.out.println("序列化之前信息:"+userInfo);
        try{
            //第二步开始序列化操作
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\1122.txt"));
            output.writeObject(userInfo);
            output.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        try{
            //第三步开始反序列化操作
            ObjectInputStream input = new ObjectInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\1122.txt"));
            //ObjectInputStream的readObject方法会抛出类找不到(ClassNotFoundException)异常
            Object o = input.readObject();
            System.out.println("反序列化之后信息:"+o);
        }catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

添加transient修饰的属性默认值为null!如果被transient修饰的属性为int类型,那么它被序列化之后的值为0!说明被标记为transient的属性在对象被序列化的时候不会被保存(或者说变量不会持久化)

4、transient关键字小结

1、变量被transient修饰,变量将不会被序列化

2、transient关键字只能修饰变量,而不能修饰方法和类

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

4、final变量值参与序列化,final transient同时修饰变量,final不会影响transient,一样不会参与序列化

第二点需要注意的是:本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口

第三点需要注意的是:反序列化后类中static型变量的值实际上是当前JVM中对应static变量的值,这个值是JVM中的并不是反序列化得出的。

结语:被transient关键字修饰导致不被序列化,其优点是可以节省存储空间。优化程序!随之而来的是会导致被transient修饰的字段会重新计算,初始化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中的transient关键字 的相关文章

  • 有什么方法可以显示正在运行的 JVM 中使用的标志吗?

    尽管我们已经为应用程序显式设置了许多 JVM 标志 但很难知道是否 1 布尔标志默认已打开 默认值在 JDK JRE 次要更新之间发生了变化 2 一个标志否定另一个标志 3 特定系统上给定任意标志的默认值是什么 由 Java 人体工程学设置
  • JVM 内存类型

    我正在做一个监控项目 我们有监控软件正在运行并从服务器重新收集指标 一切工作正常 但我们需要一些有关 JVM 内存使用情况详细信息 我们有一些具有不同内存类型的列 我们需要知道这些是什么 Heap Non Heap Usage Peak C
  • 是否可以使 java.lang.invoke.MethodHandle 与直接调用一样快?

    我正在比较性能MethodHandle invoke以及直接静态方法调用 这是静态方法 public class IntSum public static int sum int a int b return a b 这是我的基准 Stat
  • JVM HotSpot 上的 Java 异常计数器

    我想知道是否可以在不更改应用程序代码的情况下记录 JVM 级别上发生的每个异常 我所说的每个异常是指捕获和未捕获的异常 我想稍后分析这些日志并按异常类型 类 对它们进行分组 并简单地按类型对异常进行计数 我正在使用热点 也许有更明智的理由这
  • 热点 JVM 字节码解释器是跟踪 JIT 吗?

    这个问题几乎说明了一切 我一直在寻找答案 甚至通过 VM 规范 但我没有明确说明 No 不过 还有一些其他 JVM 具有跟踪 JIT HotPath http HotPath GoogleCode Com and Maxine http L
  • 我的代码中出现内存不足异常

    作为 Oracle 数据库压力测试的一部分 我正在长时间运行代码并使用 java 版本 1 4 2 简而言之 我正在做的是 while true Allocating some memory as a blob byte data new
  • STS 无法在我的计算机上启动

    我试图在 eclipse 上设置 Spring mvc 项目 基本项目进展顺利 但是使用 Restful 服务 Jersey 等开始出现许多与依赖项相关的错误 所以我打算转到STS 我正在使用 STS 2 9 2 它给我 无法创建java虚
  • Java 中的引用变量里面有什么?

    我们知道对象引用变量保存表示访问对象的方式的位 它不保存对象本身 但保存诸如指针或地址之类的东西 我正在阅读 Head First Java 第 2 版 一书 书中写道 第 3 章第 54 页 在 Java 中我们并不真正知道什么是 在引用
  • 启用JConsole远程监控是否会影响生产中的系统性能?

    Oracle Sun 说只要不在生产环境中本地运行就可以吗 http download oracle com javase 1 5 0 docs guide management jconsole html http download or
  • Scala 对大数的阶乘有时会崩溃,有时不会

    以下程序经过编译和测试 有时返回结果 有时充满屏幕 java lang StackOverflowError at scala BigInt apply BigInt scala 47 at scala BigInt equals BigI
  • 监控 Java 应用程序上的锁争用

    我正在尝试创建一个小基准 在 Groovy 中 以显示几个同步方法上的高线程争用 当监控自愿上下文切换时 应该会出现高争用 在 Linux 中 这可以通过 pidstat 来实现 程序如下 class Res private int n s
  • 在正在运行的 JVM 中查找正在运行的实例

    我想知道是否可以获取给定类的正在运行的实例的句柄 触发此问题的特定问题是应用程序由于存在大量正在运行的线程而无法正常退出 是的 我知道您可以对 thead 进行守护进程 然后它们就不会阻止应用程序退出 但这确实让我想知道这是否可能 我能做的
  • 如何在Java中计算对象的数字年龄[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道Java中对象的年龄 当我们使用new关键字时 Java中用户定义的对象被创建 但是什么时候它会被销毁 是跨越JVM的perm
  • 使用 javac 和 javax.tools.JavaCompiler 有什么区别?

    Maven 编译器插件文档states http maven apache org plugins maven compiler plugin 编译器插件用于编译项目的源代码 从 3 0 开始 默认编译器是 javax tools Java
  • Java 中清除嵌套 Map 的好方法

    public class MyCache AbstractMap
  • Java 语言中不可用的字节码功能

    当前 Java 6 是否有一些事情可以在 Java 字节码中完成而在 Java 语言中无法完成 我知道两者都是图灵完备的 所以将 可以做 理解为 可以做得更快 更好 或者只是以不同的方式 我正在考虑额外的字节码 例如invokedynami
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack
  • 为什么同样的算法在 Scala 中运行比在 C# 中慢得多?以及如何让它更快?

    该算法根据序列中每个成员的变体创建序列的所有可能变体 C 代码 static void Main string args var arg new List
  • 如果使用的 JVM 是 x86 或 x64,则以不同的方式解决 Maven 依赖关系?

    我设置了一个 Maven 存储库来托管一些 dll 但我需要我的 Maven 项目根据使用的 JVM 是 x86 还是 x64 下载不同的 dll 例如 在运行 x86 版本 JVM 的计算机上 我需要从存储库下载 ABC dll 作为依赖
  • 调整 Java 类以提高 CPU 缓存友好性

    在设计java类时 对于实现CPU缓存友好性有哪些建议 到目前为止我学到的是应该尽可能多地使用 POD 即 int 而不是整数 这样 在分配包含对象时 数据将被连续分配 例如 class Local private int data0 pr

随机推荐

  • 几个巧妙的电流检测电路

    在电源等设备中通常需要做电流检测或反馈 电流检测通常用串联采样电阻在通过放大器放大电阻上的电压的方法 如果要提高检测精度 这地方往往要用到比较 昂贵的仪表放大器 以为普通运放失调电压比较大 下面介绍几种巧妙的廉价的电流检测电路 1 三极管电
  • Window XP驱动开发(十六) XP下新建驱动程序工程并编译的第二种方法

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 需要源码的可以与我联系 参考文章 http blog 163 com ljm1113 126 blog static 579
  • CButton & CMFCRibbonButton

    CButton public CWnd CMFCRibbonButton继承自CObject 不能添加消息映射
  • vmware虚拟机双网卡 实现本地内网和网络双连接

    一 vmware新建网卡 vmware中 编辑 gt 虚拟网络编辑器 gt 更改设置 网卡配置如下 桥接本地连接 NAT网卡连接网络 二 重启虚拟机 双网卡状态下 ifconfig可以看到有两个ip 可以同时ping通百度 远程公司内网 本
  • Windows系统安装Linux系统教程

    下载VMware workstation 安装地址如下 VMware下载地址 下载好了就是这个样子 我选择的是试用30天 大家也可以找破解版安装包 下载ubuntu ubuntu桌面版下载地址 下载桌面版就好 接下来是安装过程 每一步都有详
  • 如何使用apipost进行接口测试

    在之前的文档中对apipost导入api文档进行了介绍 本次将会给大家介绍一下如何使用apipost对之前导入的接口进行测试 接口测试的介绍 首先先对接口测试进行简单的介绍 接口测试是测试系统组件间接口的一种测试 主要用于测试系统与外部其他
  • Python计算机二级考试备考(重复元素判定)

    编写一个函数 输入参数为列表 如果一个元素在列表中出现了不止一次 这返回True 同时编写调用这个函数和输出测试结果的程序 def isRepeat x if type x type return print 输入错误 请输入列表类型 el
  • 有趣的数据结构算法10——后缀表达式(PRN)介绍及利用栈计算后缀表达式的结果

    有趣的数据结构算法10 后缀表达式 PRN 介绍及利用栈计算后缀表达式的结果 解题思路 实现代码 GITHUB下载连接 在前一天已经利用栈完成2进制到8进制的转换 但是栈的应用方面还有很多 本次我将讲解如何计算后缀表达式的结果 解题思路 后
  • 知识蒸馏-Yolov3

    本人实验 利用上篇的 Learning Efficient Convolutional Networks Through Network Slimming论文阅读笔记 方法 成功将算力8 5G的darknet21 yolo模型 9个类别 m
  • ETSI最新边缘原生白皮书

    ETSI 6月底发布了由 ETSI 多接入边缘计算小组 ISG MEC 成员撰写的关于 MEC 对边缘原生设计的支持 的新白皮书 本白皮书提供了有关边缘原生方法的概述和愿景 作为云原生的自然演变 它详细解释了 Edge Native 的概念
  • Kotlin中标准库函数(apply、let、run、with、also、takeIf、takeUnless)的使用详解

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到教程 一 apply函数 apply apply函数可以看作是一个配置函数 你可以传入一个接收者 然后调用一系列函数来配置它以便使用 如果提供
  • 【FFmpeg】ffmpeg+nginx-rtmp实现视频流转发

    1 应用场景 目前的摄像头厂家能提供出来的视频流格式有限 且chrome已经禁止了对flash的支持 导致像硬盘录像机这种只能提供rtsp格式流地址的摄像头无法接入Web应用 所以不得不对视频的流地址进行分发 通过代码对流地址中的数据进行切
  • yolo 车辆测距+车辆识别+单目测距(双目测距)

    基于yolo目标检测算法实现的车前道路中的车辆和行人检测 并且可以估测出目标与本车之间的距离 一 视频展示 yolo车距1 订阅专栏获得源码 提供完整代码 无需看下文 二 单目测距原理 图中有一个车辆 且车辆在地面上 其接地点Q必定在地面上
  • JavaScript数据类型,包括原始类型和引用类型有哪些?

    问题 http bbs daxiangclass com thread 334 htm JavaScript数据类型 包括原始类型和引用类型有哪些 原始类型有五个 Number类型 专门保存数字的类型 可用于进行数学计算等的数值 Strin
  • HTTP2.0之我见

    概述 在讨论HTTP2 X 之前 先要搞清楚HTTP2 0的目的 HTTP 2 协议的主要目的是提高网页性能 以及 HTTP1 0 HTTP1 1 SPDY HTTPS之间的关系 参考 https cloud tencent com dev
  • 合批/批量渲染 (Batch)、实例化Instancing

    可以简单的理解为 批量渲染是通过减少CPU向GPU发送渲染命令 DrawCall 的次数 以及减少GPU切换渲染状态的次数 尽量让GPU一次多做一些事情 来提升逻辑线和渲染线的整体效率 但这是建立在GPU相对空闲 而CPU把更多的时间都耗费
  • 操作系统实验Ucore lab1

    lab1 前言 这是中山大学数据科学与计算机学院2019年操作系统实验中关于Ucore的项目以及实验报告 实验要求与Ucore手则有少量出入 所有源代码已经上传至github github个人主页 https starashzero git
  • vmware 进入虚拟机VMware的系统后鼠标不能点

    vmware 进入虚拟机VMware的系统后鼠标不能点 1 关闭虚拟机 重启win10 再打开虚拟机好了 2
  • JAVA经典算法40题(1)

    不多说直接上题 程序1 题目 古典问题 有一对兔子 从出生后第3个月起每个月都生一对兔子 小兔子长到第四个月后每个月又生一对兔子 假如兔子都不死 问每个月的兔子总数为多少 1 程序分析 兔子的规律为数列1 1 2 3 5 8 13 21 p
  • Java中的transient关键字

    前言 说实话学了一段时间java的朋友对于transient这个关键字依旧很陌生基本没怎么用过 但是transient关键字在java中却起到了不可或缺的地位 如果要说讲到 我觉得最可能出现的地方是IO流中对象流 也叫序列化流 的时候会讲到