使用序列化类的私有方法巧妙解决部分属性持久化问题

 

来源:http://book.51cto.com/art/201202/317465.htm

部分属性持久化问题看似很简单,只要把不需要持久化的属性加上瞬态关键字(transient关键字)即可。这是一种解决方案,但有时候行不通。例如一个计税系统和人力资源系统(HR系统)通过RMI(Remote Method Invocation,远程方法调用)对接,计税系统需要从HR系统获得人员的姓名和基本工资,以作为纳税的依据,而HR系统的工资分为两部分:基本工资和绩效工资,基本工资没什么秘密,根据工作岗位和年限自己都可以计算出来,但绩效工资却是保密的,不能泄露到外系统,很明显这是两个相互关联的类。先来看薪水类Salary类的代码:

 

public class Salary implements Serializable{  
     private static final long serialVersionUID = 44663L;     
    //基本工资  
     private int basePay;  
     //绩效工资  
     private int bonus;  

     public Salary(int _basePay,int _bonus){  
           basePay = _basePay;  
           bonus = _bonus;  
     }  
     /*getter/setter方法省略*/  

} 
 

 

 

Peron类与Salary类是关联关系,代码如下:

 

public class Person implements Serializable{  
     private static final long serialVersionUID =60407L;  
     //姓名  
     private String name;  
     //薪水  
     private Salary salary;  

     public Person(String _name,Salary _salary){  
           name=_name;  
           salary=_salary;  
     }    
     /*getter/setter方法省略*/  
} 
 

 

 

这是两个简单的JavaBean,都实现了Serializable接口,都具备了持久化条件。首先计税系统请求HR系统对某一个Person对象进行序列化,把人员和工资信息传递到计税系统中,代码如下:

 

public class Serialize {  
     public static void main(String[] args) {  
           //基本工资1000元,绩效工资2500元  
           Salary salary = new Salary(1000,2500);  
           //记录人员信息  
           Person person = new Person("张三",salary);  
           //HR系统持久化,并传递到计税系统  

           SerializationUtils.writeObject(person);  
    }  
} 
 

 

 

在通过网络传送到计税系统后,进行反序列化,代码如下:

public class Deserialize {  
     public static void main(String[] args) {  
           //技术系统反序列化,并打印信息  
           Person p = (Person)SerializationUtils.readObject();  
           StringBuffer sb = new StringBuffer();  
           sb.append("姓名:" + p.getName());  
           sb.append("\t基本工资:" + p.getSalary().getBasePay());  
           sb.append("\t绩效工资:" + p.getSalary().getBonus());  
           System.out.println(sb);  
     }  
} 
 

 

打印出的结果很简单:


  1. 姓名:张三   基本工资:1000   绩效工资:2500。 

但是这不符合需求,因为计税系统只能从HR系统中获得人员姓名和基本工资,而绩效工资是不能获得的,这是个保密数据,不允许发生泄露。怎么解决这个问题呢?你可能马上会想到四种方案:

(1)在bonus前加上transient关键字

这是一个方法,但不是一个好方法,加上transient关键字就标志着Salary类失去了分布式部署的功能,它可是HR系统最核心的类了,一旦遭遇性能瓶颈,想再实现分布式部署就不可能了,此方案否定。

(2)新增业务对象

增加一个Person4Tax类,完全为计税系统服务,就是说它只有两个属性:姓名和基本工资。符合开闭原则,而且对原系统也没有侵入性,只是增加了工作量而已。这是个方法,但不是最优方法。

(3)请求端过滤

在计税系统获得Person对象后,过滤掉Salary的bonus属性,方案可行但不合规矩,因为HR系统中的Salary类安全性竟然让外系统(计税系统)来承担,设计严重失职。

(4)变更传输契约

例如改用XML传输,或者重建一个 Web Service服务。可以做,但成本太高。

可能有读者会说了,你都在说别人的方案不好,你提供个优秀的方案看看!好的,这就展示一个优秀的方案。其中,实现了Serializable接口的类可以实现两个私有方法:writeObject和readObject,以影响和控制序列化和反序列化的过程。我们把Person类稍做修改,看看如何控制序列化和反序列化,代码如下:

public class Person implements Serializable{  
     private static final long serialVersionUID =60407L;  
     //姓名  
     private String name;  
     //薪水  
     private transient Salary salary;  
     public Person(String _name,Salary _salary){  
           name=_name;  
           salary=_salary;  
     }    
     //序列化委托方法  
     private void writeObject(java.io.ObjectOutputStream out)
                  throws IOException {  
           out.defaultWriteObject();  
           out.writeInt(salary.getBasePay());  
     }  
     //反序列化时委托方法  
     private void readObject(java.io.ObjectInputStream in) 
                          throws IOException,ClassNotFoundException {  
        in.defaultReadObject();  
        salary = new Salary(in.readInt(),0);  
    }  
} 
 

 

其他代码不做任何改动,我们先运行看看,结果为:


  1. 姓名:张三   基本工资:1000   绩效工资:0 。 

我们在Person类中增加了writeObject和readObject两个方法,并且访问权限都是私有级别,为什么这会改变程序的运行结果呢?其实这里使用了序列化独有的机制:序列化回调。Java调用ObjectOutputStream类把一个对象转换成流数据时,会通过反射(Reflection)检查被序列化的类是否有writeObject方法,并且检查其是否符合私有、无返回值的特性。若有,则会委托该方法进行对象序列化,若没有,则由ObjectOutputStream按照默认规则继续序列化。同样,在从流数据恢复成实例对象时,也会检查是否有一个私有的readObject方法,如果有,则会通过该方法读取属性值。此处有几个关键点要说明:

(1)out.defaultWriteObject()

告知JVM按照默认的规则写入对象,惯例的写法是写在第一句话里。

(2)in.defaultReadObject()

告知JVM按照默认规则读入对象,惯例的写法也是写在第一句话里。

(3)out.writeXX和in.readXX

分别是写入和读出相应的值,类似一个队列,先进先出,如果此处有复杂的数据逻辑,建议按封装Collection对象处理。

可能有读者会提出,这似乎不是一种优雅的处理方案呀,为什么JDK没有对此提供一个更好的解决办法呢?比如访问者模式,或者设置钩子函数(Hook),完全可以更优雅地解决此类问题。我查阅了大量的文档,得出的结论是:无解,只能说这是一个可行的解决方案而已。

再回到我们的业务领域,通过上述方法重构后,其代码的修改量减少了许多,也优雅了许多。可能你又要反问了:如此一来,Person类也失去了分布式部署的能力啊。确实是,但是HR系统的难点和重点是薪水计算,特别是绩效工资,它所依赖的参数很复杂(仅从数量上说就有上百甚至上千种),计算公式也不简单(一般是引入脚本语言,个性化公式定制),而相对来说Person类基本上都是“静态"属性,计算的可能性不大,所以即使为性能考虑,Person类为分布式部署的意义也不大。

[Unity开发] [PICO]避坑指南:PICO商店上传APP时PXR Platform APPID设定详解 PICO开发者上传Unity应用时常见的"APPID不符"问题,主要源于混淆了开发者后台两个不同位置的APPID。 阅读详情

相关推荐

Excel药品说明书数据库:从零开始搭建医药数据查询系统(附完整模板)

本文详细介绍了如何从零开始搭建Excel药品说明书数据库,提供完整的医药数据查询系统模板。涵盖数据库架构设计、数据清洗标准化、智能查询系统搭建及维护优化,帮助医药从业者高效管理药品信息,提升查询速度和准确性。

weixin_28327051的博客 234

PHP反序列化入门教程(二)

概念约定:​ 类内访问:通过类内的方法访问属性/方法。​ 类外访问:类外创建对象,直接访问属性/方法protect 访问权限:只有子类,父类自己可以类内访问到,类外不行​ protect 修饰的属性:类内设置访问属性的接口(public),类外的子类,本类创建对象调用接口从而访问属性​ protect 修饰的方法:类内设置访问属性的接口(public),类外的子类,本类创建对象调用接口从而调用方法private 访问权限:只有父类自己可以类内访问,类外不行。

weixin_46003602的博客 1675

Outlook邮件备份全攻略:从导出到导入的完整流程(附常见问题解决)

本文提供了一份详尽的Outlook邮件备份全攻略,涵盖从导出到导入的完整流程。重点解析了经典桌面版Outlook的.pst文件备份方法、进阶的智能筛选备份策略,以及如何通过导入恢复和工具验证确保备份可用。同时,文章还介绍了构建自动化备份体系与异地容灾的最佳实践,并附有常见问题解决方案,帮助用户建立可靠的邮件数据安全防线。

weixin_29248611的博客 891

Day46 PHP反序列化&原生类&漏洞绕过&公私有属性

当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。// __isset():当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。/*__get() 魔术方法 读取一个对象的属性时,若属性存在,则直接返回属性值;/*__unset():在不可访问的属性上使用unset()时触发 销毁对象的某个属性时执行此函数。// _invoke():以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

wanjia01的博客 958

华为Atlas 300I推理卡驱动安装避坑指南:不同安装方式的选择与优化

本文详细解析华为Atlas 300I推理卡驱动安装的三种主流方式(.run、.rpm和源码编译),提供关键环境检查步骤、安装流程优化建议及常见问题解决方案,帮助开发者高效完成芯片推理卡部署并规避典型安装陷阱。

q9w8e7r6t5的博客 431

4.图像sensor的特性和驱动解析

例子:sensor驱动自己提供操作曝光时间的函数和获取曝光时间的函数,然后将这个函数注册到ISP库和3A算法库,3A算法库根据外部光照强度计算出一个Sensor曝光时间的设置值,ISP库得到这个设置值,然后通过Sensor之前注册的回调函数,把这个值设置到Sensor的硬件寄存器中去,实现整个过程。是为 ISP 配置正确的输入时序。(1)修改驱动源码(sambashar\Hi3518E_SDK_V1.0.3.0\package\mpp\component\isp\sensor\ar0130)

weixin_53762042的博客 3566

public、protected与private在序列化时的区别

protected 声明的字段为保护字段,在所声明的类和该类的子类中可见,但在该类的对象实例中不可见。因此保护字段的字段名在序列化时,字段名前面会加上 \0*\0 的前缀,注意,这里的 \0 表示 ASCII 码为 0 的字符,也就是我们经过 urlencode 后看到的 %00 。 private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,字段名前面会加上 \0<declared class name>\0 的前缀,这里

qq_45707441的博客 2389

基于STM32与CAN总线的多电机协同控制系统设计与实现

本文详细介绍了基于STM32与CAN总线的多电机协同控制系统设计与实现。该系统采用分布式架构,通过CAN总线实现多节点通信,结合梯形加减速算法和同步控制策略,有效解决了工业自动化中多电机同步性差的问题。文章涵盖硬件设计、通信协议、抗干扰措施及实战调试经验,为工业应用提供高可靠性解决方案。

tech5的博客 970

Java使用序列化的私有方法巧妙解决部分属性持久化问题

部分属性持久化问题看似很简单,只要把不需要的持久化的属性加上瞬态关键字(transient关键字)即可,没错,这也是一种解决方案,但在有的时候行不通,例如在一个计税系统和人力系统对接的时候,计税系统需要从人力系统获得人员的姓名和基本工资,作为纳税的一句,而人力系统的工资分成 分成两个部分:基本工资和绩效工资,基本工资没有什么秘密,一般都是直接跟年限挂钩,但是绩效工资一般来说是保密的,不能泄露到外系...

weixin_34301307的博客 233

iPhone用户必看:TrollStore巨魔商店在线安装保姆级教程(iOS 14-16.6.1适用)

本文为iOS 14至16.6.1系统的iPhone用户提供了一份详细的TrollStore(巨魔商店)在线安装教程。文章从核心原理、安装前准备讲起,逐步详解了通过Safari浏览器获取安装器、信任企业证书、部署TrollStore及关键后置配置的全过程,并附带了常见问题排错指南,帮助用户安全、高效地实现无需越狱安装第三方应用。

h0i1j2k3l的博客 1995

loadStop的原因导致的SSUSP

Total内存值是可用来调度的可用内存,当前可用内存为 0M。 loadSched和loadStop的阈值是根据 Total 内存和节点内存来做限制的。 loadStop 50G,现在有大量作业SSUSP,说明之前某个时间点该节点内存可能有低于50G的时候,导致作业SSUSP,具体是否是这个原因引起的需要用 bjobs -l JobID 看下作业的详细信息。 如果是loadStop的原因导致的 SSUSP,根据loadStop设置的阈值,Total 值高于loadStop值后,将逐步恢复挂起的作业

Blueberry521的博客 666

java序列化 持久化_Java使用序列化的私有方法巧妙解决部分属性持久化问题

部分属性持久化问题看似很简单,只要把不需要的持久化的属性加上瞬态关键字(transient关键字)即可,没错,这也是一种解决方案,但在有的时候行不通,例如在一个计税系统和人力系统对接的时候,计税系统需要从人力系统获得人员的姓名和基本工资,作为纳税的一句,而人力系统的工资分成 分成两个部分:基本工资和绩效工资,基本工资没有什么秘密,一般都是直接跟年限挂钩,但是绩效工资一般来说是保密的,不能泄露到外系...

weixin_42304279的博客 246

3、灵巧手的设计与构造

本文详细探讨了灵巧手的设计与构造,包括多指结构、关节和连杆设计、传感器集成以及分层控制架构等内容。同时,通过工业装配、医疗手术辅助和日常生活辅助等实际应用案例,展示了灵巧手的灵活性和适应性,并分析了当前设计面临的挑战及未来发展方向。

brandy的博客 491

Java - 如果你的Serializable类包含一个不可序列化的成员,会发生什么?你是如何解决的?

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 任何序列化该类的尝试都会因NotSerializableException而失败,但这可以通过在Java中为其设置瞬态(trancient)变量来轻松解决。 Java序列化相关的常见问题 Java序列化是一个重要概念,但它很少用作持久性解决方案,...

了解➔熟悉➔掌握➔精通 4万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

python对象序列化或持久化的方法

一、Python对象持久化方法 目前为止,据我所知,在python中对象持久化有以下几种方法: 1. 使用(dbhash/bsddb, dbm, gdbm, dumbdbm 等)以及它们的"管理器"( anydbm )。只提供了 Python 字  符串的永久性储存. 提供一个类似字典和文件的对象,可以完成字符串的永久性存储。 2. 使用marshal和pickle来序列化py

chen_lovelotus的专栏 2013

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

一文解决序列化&反序列化体系

序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在Java中,这通常意味着将一个对象(通常是一个实现了接口的类的实例)转换成一系列字节,这些字节可以被保存到文件中或通过网络发送到另一个位置。这样做的目的主要是实现两个目标:持久化存储:通过序列化,对象可以被永久地保存到存储介质(如硬盘)上,即使程序结束运行,对象的状态也可以被保存下来,并在需要时重新加载。网络传输:序列化后的字节流可以通过网络发送给其他计算机,实现对象在不同计算机之间的共享。总结:将数据结构或对象转换成二进制字节流的过程。

zhouhengzhe的博客 2171

类对象的持久化与序列化

1、所谓类对象的持久化是指:把内存中的对象存储在某种介质上(除内存外,包括硬盘或者网络存储传输等),当然持久化的完整操作并不只是为了把对象数据以字节码或字节流的形式存储在介质上,它还要包括对持久化的对象读取与验证。2、所谓类对象的序列化是指:把一个类对象转化为字节流或字节码(把一个字节流对象转化为一个类对象过程称为反序列化),同时保存其状态等一些特性。对象序列化需要继承Serializable接口,

qq_26564827的博客 1507

编写高质量代码:改善Java程序的151个建议(第1章:Java开发中通用的方法和准则___建议14~20)...

作为一个由影视圈转行做Java的菜鸟来说,读书是很关键的,本系列是用来记录《编写高质量代码 改善java程序的151个建议》这本书的读书笔记。方便自己查看,也方便大家查阅。 建议14:使用序列化类的私有方法巧妙解决部分属性持久化问题 建议15:break万万不可忘 建议16:易...

chetianyao8457的博客 384

Java序列化篇(一):详解Java中的序列化

Java 中的序列化允许我们将对象转换为流,从而可以通过网络发送、保存为文件或存储到数据库中以供后续使用。反序列化是将对象流转换回实际的 Java 对象,以便在程序中使用的过程。Java 中的序列化起初看起来非常容易使用,但它伴随着一些显而易见的安全性和完整性问题,我们将在本文后面部分进行探讨。

weixin_48681435的博客 1158

实体类序列化问题

实体类序列化 文章借鉴他人加上自己的部分理解 一、java实体类为什么要序列化? 客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。 ​

imbestman的博客 1695

序列化的一些注意事项及建议

本文来自《改善java的151个建议》 建议11:养成良好习惯,显示声明UID 我们先写一个序列化与反序列化的工具类SerilizationUtils public class SerializationUtils { private static String FILE_NAME="E:/serializable.txt"; public stati...

石臻说AI(szzdzhp001) 【原名 石臻臻的杂货铺】 2108

4.9 Python 数据持久化与 Pickle 序列化

Python Pickle模块提供了强大的对象序列化功能,能够将复杂对象(包括自定义类实例)转换为字节流存储或传输。本文介绍了Pickle的核心概念、基础用法(序列化/反序列化)、协议版本选择,以及处理自定义对象、循环引用和自定义序列化逻辑的高级技巧。通过代码示例展示了如何实现数据持久化,同时保持对象完整性和引用关系。Pickle是存储Python特有数据结构的高效工具,适用于需要保存完整对象状态的场景。

ylumwd的博客 795

序列化和持久化的区别

持久化(Persistence) 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。 持久化是将程序数据在持久状态和瞬时状态间转换的机制。 JDBC就是一种持久化机制。文件IO也是一种持久化机制。 持久化是一种对象服务,就是把内存中的对象保存到外存中,让以后能够取回。需要实...

窗台有只猫的博客 165

Java对象序列化 系统解耦与序列化、持久化

系统解耦与序列化、持久化      从开始学习和实践系统设计起就一直围绕着这样一个问题——怎样降低系统的耦合度,使系统更加健壮、更加灵活?无论桌面应用还是网络应用,确实它的系统中无非包含如下几方面的内容——如何获取及存储数据、如何处理事务逻辑、如何用用户交互。在早期的系统内,由于其本身复杂性比较低,同时使用面较窄又基本不涉及移植或升级的问题,就算有也是波及面很窄,所以以上这些内容大多被混杂

achun2050的专栏 2076

Serializable序列化为什么要使用SerialversionUID

为什么要序列化对象 为什么要使用SerialversionUID 怎么生成SerialversionUID 附:如何生成UUID 参考文章:【GraceJava--Java对象序列化为什么要使用SerialversionUID】 为什么要序列化对象 把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的反序列化。   对象的序列化主要有两种用途:   1...

Imfondof 1007
上一篇: Resin配置文件中文说明
下一篇: 模拟测试概述
gufengjava
博客等级 码龄16年 1粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值