java提高(6)---Serializable
Serializable--初解
一 序列化是干什么的?
我们知道,在jvm中引用数据类型存在于栈中,而new创建出的对象存在于堆中。如果电脑断电那么存在于内存中的对象就会丢失。那么有没有方法将对象保存到磁盘(对象持久化存储)或通过网络传输到远处的其他地方呢?
答案是可以,但是我们必须要求所有支持持久化存储的类实现Serializable接口。Serializable就像个通行证,只有持有这个通行证,jvm才让类创建的对象进行持久化。这个接口将类与一个称为serialVersionUID的变量关联起来,这个serialVersionUID就是在反序列化中用来确定由哪个类来加载这个对象。
二、什么情况下需要序列化
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
三、JavaBean为什么要实现java.io.Serializable接口实现序列化?
找了个比较好理解的例子:客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。
web服务器通常将那些暂时不活动但未超时的HttpSession对象转移到文件系统或数据库中保存,服务器要使用他们时再将他们从文件系统或数据库中装载入内存,这种技术称为Session的持久化。
将HttpSession对象保存到文件系统或数据库中,需要采用序列化的方式将HttpSession对象中的每个属性对象保存到文件系统或数据库中;将HttpSession对象从文件系统或数据库中装载如内存时,需要采用反序列化的方式,恢复HttpSession对象中的每个属性对象。所以存储在HttpSession对象中的每个属性对象必须实现Serializable接口。当然如果不是存储在session中的JavaBean可以不用存储哈。
举个简单例子:
Student
import java.io.Serializable;
public class Student implements Serializable {
/*serialVersionUID来决定由哪个类来加载存在于文件中的对象
* 如果指定serialVersionUID的数值,那就能使得其不再与类的成员变量相关联
* 不然你已经把对象保存到数据库,这个时候你再给这个对象新增属性,那么反序列化
* 就会报:本地类不匹配的错误,但如果指定serialVersionUID值那就不会报错。
*/
private static final long serialVersionUID = -5182532647273106745L; //成员变量写成static的话是不能被持久化的
public static String countryName="china";
private String name;
private int age;
//如果想对非静态的数据也不想序列化,则需要加入关键字
transient String sex;
/* 提供set和get方法,无参和有参方法*/
}
测试类
import java.io.*;
public class SerializableTest {
public static void main(String[] args) {
writeObj();
readObj();
}
public static void writeObj()
{
Student student=new Student("小筱", 1, "女");
try {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\student.txt"));
oos.writeObject(student);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readObj()
{
try {
ObjectInputStream ooi=new ObjectInputStream(new FileInputStream("d:\\student.txt"));
try {
Object obj=ooi.readObject();
Student student=(Student)obj;
System.out.println("age:"+student.getAge()+",name:"+student.getName()+",countryName:"+student.countryName+",sex:"+student.getSex());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ooi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
第二个小例子我没有亲自测试:用套接字在网络上传送对象
1.首先建立要传输的对象
//建立用来持续化的对象
import java.io.Serializable;
public class ObjectSeri implements Serializable{ //成员变量写成static的话是不能被持久化的
//private关键字是不能被持久化的,脱离了JVM,成员变量是不在JVM的安全机制之内
private String name;
private String age;
/*set和get方法*/ <span style="color:#333333;"><strong>
</strong></span>
2.有了传输的对象,下一步就是建立一个服务端线程来监听socket端口,并且在run方法里面实现读取对象的数据
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
//serverTest类继承thread类,监听端口来的信息
public class serverTest extends Thread {
// private final String serverIP = "127.0.0.1";
private final int serverPort = 3400;
private ServerSocket server;
public serverTest() {
try {
// ServerSocket server=new ServerSocket(serverPort);
server = new ServerSocket(serverPort);
System.out.println("正在监听3400端口");
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
Socket socket = null;
ObjectInputStream in;
while (true) {
try {
synchronized (server) {
socket = server.accept();
}
System.out.println("当前的连接是:"
+ socket.getInetAddress().toString());
socket.setSoTimeout(20000);
in = new ObjectInputStream(socket.getInputStream());
ObjectSeri data = (ObjectSeri) in.readObject();
System.out.println("The name is:" + data.getName()
+ "and age is:" + data.getAge());
in.close();
in = null;
socket.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
(new serverTest()).start();
}
3.最后,建立一个客户端来测试下
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
//建立一个client测试类
public class TestClient {
private String address = "127.0.0.1";
private int port = 3400; public TestClient() {
// Prepare the data need to transmit
ObjectSeri data = new ObjectSeri();
data.setName("Scott");
data.setAge("34");
Socket client = new Socket();
InetSocketAddress adr = new InetSocketAddress(this.address, this.port);
try {
client.connect(adr, 10000);
ObjectOutputStream out = new ObjectOutputStream(
client.getOutputStream());
// send object
out.writeObject(data);
out.flush();
out.close();
out = null;
data = null;
client.close();
client = null;
} catch (java.io.IOException e) { System.out.println("IOException :" + e.toString());
}
}
public static void main(String[] args) {
new TestClient();
}
} <span style="color: rgb(51, 51, 51);"> </span>
输出结果如下:
正在监听3400端口
当前的连接是:/127.0.0.1
The name is:Scottand age is:34
今天:2017:12:05 发现自己用到了,就是jquery表单提交,用post提交,这样有个最大的好处,就是我不用一个值一个值提交,而是把表单提交过去
$.post('your url', $("form").serialize(), function(data) {
// your code
}
});
小筱的窝:水滴石穿,成功的速度一定要超过父母老去的速度! 少尉【2】
java提高(6)---Serializable的更多相关文章
- 【java提高】Serializable(一)--初步理解
Serializable(一)--初步理解 一 序列化是干什么的? 我们知道,在jvm中引用数据类型存在于栈中,而new创建出的对象存在于堆中.如果电脑断电那么存在于内存中的对象就会丢失.那么有没有方 ...
- Java提高篇——对象克隆(复制)
假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...
- java提高篇(二九)-----Vector
在java提高篇(二一)-–ArrayList.java提高篇(二二)-LinkedList,详细讲解了ArrayList.linkedList的原理和实现过程,对于List接口这里还介绍一个它的实现 ...
- Java提高篇(二八)------TreeSet
与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的.在<Java提高篇(二七)-----TreeMap>中LZ详细讲解了TreeMap实现机制,如果 ...
- Java提高篇(二七)-----TreeMap
TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做:根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致 ...
- java提高篇(二四)-----HashSet
在前篇博文中(java提高篇(二三)-----HashMap)详细讲解了HashMap的实现过程,对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素. ...
- java提高篇(十九)-----数组之二
前面一节主要介绍了数组的基本概念,对什么是数组稍微深入了一点点,在这篇博文中主要介绍数组的其他方面. 三.性能?请优先考虑数组 在java中有很多方式来存储一系列数据,而且在操作上面比数组方便的多?但 ...
- Java提高篇---TreeMap
TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做:根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致 ...
- java提高篇(二二)-----LinkedList
摘自http://blog.csdn.net/chenssy/article/details/18099417 java提高篇(二二)-----LinkedList 一.概述 LinkedList与 ...
- Java中的Serializable接口和transient关键字
Java中的Serializable接口和transient关键字 Table of Contents 1. 向memcached中放数据时遇到NotSerializableException异常 2 ...
随机推荐
- Linux二进制分析PDF
链接:https://pan.baidu.com/s/1lp5mz30J3RamFyQIXRvx5w 提取码:vcdq 我就是看不惯csdn的付费下载,链接失效了就评论区留言,我能收到邮件.
- suse11 安装 python3.6 python3 安装步骤
首先需要去网上下载Python-3.6.4.tgz,libopenssl-devel-0.9.8j-2.1.x86_64.rpm zlib-devel-1.2.7-3.14.x86_64.rpm li ...
- Exp 8 Web基础
Exp 8 Web基础 20154305 齐帅 一.实践要求: (1).Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. ...
- ES6学习:两个面试题目--关于模板字符串
号称看完就能“让开发飞起来”,不过文中的两个面试题目的知识点并没包括在文中. https://www.jianshu.com/p/287e0bb867ae 文中并没有完整的知识点去完成上面的两道题,这 ...
- python循环解压rar文件
python循环解压rar文件 C:. │ main.py │ ├─1_STL_算法简介 │ STL_算法简介.rar │ └─2_STL_算法_填充新值 STL_算法_填充新值.rar 事情是这样的 ...
- 时序扩展的UML状态图的测试用例生成研究
一.基本信息 标题:时序扩展的UML状态图的测试用例生成研究 时间:2014 出版源:西南大学 领域分类:时序扩展:UML状态图:测试用例:需求规格说明:模型 二.研究背景 问题定义:时序扩展的UML ...
- Activiti工作流数据库表详细介绍
Activiti的后台是有数据库的支持,所有的表都以ACT_开头. 第二部分是表示表的用途的两个字母标识. 用途也和服务的API对应. ACT_RE_*: 'RE'表示repository. 这个前缀 ...
- Requests+正则表达式抓取猫眼电影TOP100
spider.py # -*- coding:utf-8 -*- import requests import re import json import codecs from requests.e ...
- Python 字符串十六进制流
字符串转十六进制绕过特征检测SQL注入 Python中内置库与出色第三方库的学习 # 字符串转十六进制 mystr = "hello world" print(":&qu ...
- Shader 屏幕后期特效 Shake(震屏)&Wave(波纹)
震屏效果 Shader: //////////////////////////////////////////// ///// CameraPlay - by VETASOFT 2017 ///// ...