- 浏览: 713087 次
- 来自: ...
文章分类
最新评论
-
ranguisheng:
可以加点注释,代码不便于阅读.
用java实现数据库连接池的一个简单示例 -
abcd880129:
这样写的话,还要用专门的下载工具,不然,只能下到一个为空的ex ...
ZK下载文件时,不在服务器生成文件直接下载 -
234369425:
同上,是20
java计算阶乘 -
CodeToMyLaw:
如果目录中含有中文呢?
[^\x00-\xff] 中文的 ...
js验证文件目录格式的正确性 -
yanzhoupuzhang:
加了,还是报那个错误!
org.apache.commons.dbcp.BasicDataSource的解决方法
序列化概述
简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)!在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!
问题的引出:
如上所述,读写对象会有什么问题呢?比如:我要将对象写入一个磁盘文件而后再将其读出来会有什么问题吗?别急,其中一个最大的问题就是对象引用!举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); },这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!
以下序列化机制的解决方案:
1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)
2.当要保存一个对象时,先检查该对象是否被保存了。
3.如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象
通过以上的步骤序列化机制解决了对象引用的问题!
序列化的实现
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
修改默认的序列化机制
在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然也不可被恢复。但有时我们想将某一字段序列化,但它在SDK中的定义却是不可序列化的类型,这样的话我们也必须把他标注为transient,可是不能写入又怎么恢复呢?好在序列化机制为包含这种特殊问题的类提供了如下的方法定义:
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream out) throws IOException;
(注:这些方法定义时必须是私有的,因为不需要你显示调用,序列化机制会自动调用的)使用以上方法我们可以手动对那些你又想序列化又不可以被序列化的数据字段进行写出和读入操作。
-----------------------------------------------------------
下面是一个典型的例子,java.awt.geom包中的Point2D.Double类就是不可序列化的,因为该类没有实现Serializable接口,在我的例子中将把它当作LabeledPoint类中的一个数据字段,并演示如何将其序列化!
简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)!在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!
问题的引出:
如上所述,读写对象会有什么问题呢?比如:我要将对象写入一个磁盘文件而后再将其读出来会有什么问题吗?别急,其中一个最大的问题就是对象引用!举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); },这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!
以下序列化机制的解决方案:
1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)
2.当要保存一个对象时,先检查该对象是否被保存了。
3.如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象
通过以上的步骤序列化机制解决了对象引用的问题!
序列化的实现
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
import java.io.*; ----------------------------------------------------------- class Employee implements Serializable { public Employee(String n, double s) { name = n; salary = s; } /** *加薪水 */ public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } public String toString() { return getClass().getName() + "[name = "+ name + ",salary = "+ salary + "]"; } private String name; private double salary; } class Manager extends Employee { public Manager(String n, double s) { super(n, s); secretary = ; } /** *设置秘书 */ public void setSecretary(Employee s) { secretary = s; } public String toString() { return super.toString() + "[secretary = "+ secretary + "]"; } //secretary代表秘书 private Employee secretary; }
修改默认的序列化机制
在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然也不可被恢复。但有时我们想将某一字段序列化,但它在SDK中的定义却是不可序列化的类型,这样的话我们也必须把他标注为transient,可是不能写入又怎么恢复呢?好在序列化机制为包含这种特殊问题的类提供了如下的方法定义:
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream out) throws IOException;
(注:这些方法定义时必须是私有的,因为不需要你显示调用,序列化机制会自动调用的)使用以上方法我们可以手动对那些你又想序列化又不可以被序列化的数据字段进行写出和读入操作。
-----------------------------------------------------------
下面是一个典型的例子,java.awt.geom包中的Point2D.Double类就是不可序列化的,因为该类没有实现Serializable接口,在我的例子中将把它当作LabeledPoint类中的一个数据字段,并演示如何将其序列化!
import java.io.*; import java.awt.geom.*; public class TransientTest { public static void main(String[] args) { LabeledPoint label = new LabeledPoint("Book", 5.00, 5.00); try { System.out.println(label);//写入前 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Label.txt")); out.writeObject(label); out.close(); System.out.println(label);//写入后 ObjectInputStream in = new ObjectInputStream(new FileInputStream("Label.txt")); LabeledPoint label1 = (LabeledPoint)in.readObject(); in.close(); System.out.println(label1);//读出并加1.0后 } catch (Exception e) { e.printStackTrace(); } } }
发表评论
-
Json,Gson,FastJson解析笔记
2015-06-13 17:31 939Json 1.将JavaBean转换成Json对象: pu ... -
String与InputStream互转的几种方法
2015-06-13 17:24 769/** * 利用BufferedReader ... -
Java压缩图片
2015-06-06 15:49 1120package com.yipai.ut ... -
HashMap的工作原理
2013-11-18 22:58 878本文由 ImportNew - 唐小娟 翻译自 Javarev ... -
一道多线程题目的解决方案
2013-08-03 17:24 835在iteye上看到的一道多线程的题目,参考了一下网友的实现,那 ... -
java socket 多线程网络传输多个文件
2013-06-25 14:57 885由于需要研究了下用 java socket 传输文件,由于需要 ... -
处理大数字
2011-04-30 13:40 1019/** * 处理大数字 * & ... -
生成随机数
2011-04-30 13:39 1244/** * 生成随机数 */ public cl ... -
转换数字的进制
2011-04-30 13:38 1327/** * * 转换数字的进制 */ pu ... -
数字的舍入
2011-04-30 13:37 1110/** * 数字的舍入 * */ publi ... -
格式化数字
2011-04-30 13:36 1173/** * 格式化数字的输出 * */ pu ... -
数字与其封装类之间的转换
2011-04-30 13:16 853/** * * 数字与其封装类之间的转换 * ... -
Adapter适配器模式
2011-04-24 21:38 884/** * Adapter适配器模式<br> ... -
Factory工厂模式
2011-04-24 21:36 913/** * 模式名称:工厂模式 * 模式特征:通过 ... -
Singleton单例模式
2011-04-24 21:35 1007public class SingletonA { ... -
排序类
2011-04-24 20:38 1019/** * 定义数字排序的 ... -
方法和变量在继承时的覆盖与隐藏
2011-04-24 20:30 983public class Parent2 { // ... -
类的加载顺序
2011-04-24 20:27 866/** * 父类 * */ public ... -
自定义形状类(继承的运用)
2011-04-10 17:18 1140/** * * 自定义图形的基类 */ p ... -
myeclipse8.6 注册码
2011-04-10 14:17 1183package com.springemail; i ...
相关推荐
13. **I/O流**:Java的I/O流系统支持数据的输入和输出,包括字符流和字节流,以及过滤流、缓冲流、对象序列化等高级功能。 14. **反射**:反射机制允许程序在运行时动态获取类的信息(如类名、方法名等)并调用方法...
- 对象序列化与反序列化:Serializable接口,实现对象的持久化。 6. **线程**: - 线程的创建:Thread类和Runnable接口。 - 线程同步:synchronized关键字,wait()、notify()和notifyAll()方法,Lock接口。 - ...
笔记会讲解字节流和字符流的区别,以及如何使用缓冲区提高效率,还会涵盖文件流、网络流和对象序列化。 ### 6. 集合框架(8:Java Collections FrameWork-Java API 实战.md) Java集合框架是管理对象的容器,如...
11. **IO流**:理解输入输出流的概念,学习文件操作、对象序列化等。 12. **多线程**:理解并发编程的基本概念,掌握线程的创建和管理。 13. **设计模式**:介绍常见的设计模式,如单例模式、工厂模式、装饰者模式...
在Java编程语言中,面向对象特性是其核心概念之一,其中引用来传递对象是一个非常重要的知识点。本教程将深入探讨Java中的引用传递机制,并通过视频教程的形式帮助学习者更好地理解和应用这一概念。 首先,理解...
9. **IO流**:Java的IO流用于处理输入输出,包括字节流和字符流,以及对象序列化和反序列化。 10. **多线程**:Java内置对多线程的支持,可以创建并发执行的任务,提高程序性能。 在提供的“test.txt”文本文件和...
Java是一种面向对象的编程语言,它的核心特性包括抽象、接口和抽象类、继承、多态以及封装。在Java培训课程中,理解并掌握这些概念至关重要。 面向对象是Java的基础,它将现实世界的问题转化为计算机程序的过程。...
- 文件与流:文件操作、字节流与字符流、缓冲流、对象序列化。 - 多线程:线程的创建、线程同步与通信(synchronized、wait()、notify()、join())。 - 输入输出系统:Scanner、System.in、File类、FileReader/...
- **对象序列化**:Java对象可以通过序列化持久化到磁盘或在网络间传输。 9. **多线程** - **线程的创建与状态**:通过Thread类或实现Runnable接口创建线程,了解线程的生命周期和状态转换。 - **同步与互斥**:...
本课件“面向对象Java课件”旨在为初学者提供一个深入理解Java面向对象特性的平台,同时也适合有一定经验的开发者进行复习和巩固。 在Java中,面向对象主要涉及三大核心概念:封装、继承和多态。封装是将数据和操作...
10. **第十四章 高级IO编程**:Java的IO系统强大而灵活,本章可能涵盖流的概念、文件操作、缓冲区、对象序列化等高级内容,这对于处理数据输入输出的场景非常关键。 尽管缺失了几章,但保留的部分已经足够构建一个...
Java面向对象是Java编程的核心,理解其概念和特性对于成为一名合格的Java开发者至关重要。下面将详细阐述面试中可能涉及的一些关键知识点。 1. **super()与this()的区别**: - `this`关键字用于引用当前类的对象,...
这份实验报告的内容涵盖了Java面向对象编程的基础知识和实践技能。它不仅介绍了Java语言的基本概念,还提供了具体的编程练习和实验步骤,帮助学习者加深对Java语言的理解和应用。以下是报告中所涉及的关键知识点和...
根据给定的教学大纲,我们可以将Java面向对象编程的关键知识点总结如下: ### Java简介 #### 目标 - **了解Java语言**:理解Java的历史、功能及其可创建的程序类型。 - **了解Java的特点**:包括平台无关性、简单...
13. 输入/输出(I/O):Java的I/O流系统为读写文件、网络通信提供了丰富的API,包括字节流、字符流、缓冲流、对象序列化等。 以上就是Java面向对象编程的主要知识点,对于初学者来说,理解并熟练运用这些概念是掌握...
本资源涵盖了面向对象编程的基础知识,包括对象的定义和使用、static修饰的应用、final修饰的使用、重载的实现、基于抽象类和接口的重写、包的定义、类的导入、类的权限、类中成员权限、异常处理机制、线程构造、...
本练习将重点讲解XML与面向对象编程中的封装、以及序列化和反序列化的概念。 首先,面向对象编程(Object-Oriented Programming, OOP)是程序设计的一种重要范式,它的核心思想是将数据和处理这些数据的方法封装在...