POJO和JavaBean的区别

POJO(plain ordinary javaobject):“简单普通Java对象”
①有一些属性为private
②针对每一个属性定义getset方法接口
③没有任何类继承,也没有实现任何接口,更没有其他框架入侵的java对象
示例:

public class BasicInfoVo {

	private String orderId;
	
	private Integer uid;
	
	
	public String getOrderId() {
	    return orderId;
	}
	
	public void setOrderId(String orderId) {
	    this.orderId = orderId;
	}
	
	public Integer getUid() {
	    return uid;
	}
	
	public void setUid(Integer uid) {
	    this.uid = uid;
	}
}

JavaBean:是一种Java语言编写的可重用的组件
①所有属性为private
②有一个无参构造器
③这个类属性使用gettersetter来访问,其他方法遵从标准命名规范
④这个类的接口是可序列化的,实现serializable接口
示例:

public class UserInfo implements java.io.Serializable{  
  
//实现serializable接口。  
	private static final long serialVersionUID = 1L;  
	  
	private String name;  
	private int age;  
	  
	//无参构造器  
	public UserInfo() {  
	      
	}  
	
	public String getName() {  
	    return name;  
	}  
	
	public void setName(String name) {  
	    this.name = name;  
	}  
	
	public int getAge() {  
	    return age;  
	}  
	
	public void setAge(int age) {  
	    this.age = age;  
	}  
	
	//javabean当中可以有其它的方法  
	public void userInfoPrint(){  
	    System.out.println("");  
	} 
 }  

区别:
POJO其实是比javabean更纯净的简单类或接口。POJO严格地遵守简单对象的概念,而一些JavaBean中往往会封装一些简单逻辑。
POJO主要用于数据的临时传递,它只能装载数据, 作为数据存储的载体,而不具有业务逻辑处理的能力。
Javabean虽然数据的获取与POJO一样,但是javabean当中可以有其它的方法。

备注:
Serializable接口属于标志接口,这个接口没有任何的方法定义,它仅仅只是标记某个类能被序列化和反序列化。(接口不包含任何方法)
一、什么是序列化?
【将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其当前状态写入到临时存储区或持久性存储区,之后,便可以通过从存储区中读取或反序列化对象的状态信息,来重新创建该对象】
序列化将数据分解成字节流,以便存储在文件中或在网络上传输。
反序列化就是打开字节流并重构对象。
二、什么情况下需要序列化?
【当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化】
三、Serializable主要用来支持两种主要的特性:
1、JavaRMI(remote method invocation),RMI允许像在本机上一样操作远程机器上的对象,当发送消息给远程对象时,就需要用到序列化机制来发送参数和接受返回值。
2、JavaJavaBeanBean的状态信息通常是在设计时配置的,Bean的状态信息必须被保存下来,以便当程序运行时能恢复这些状态信息,这也需要序Serializable机制。

只需要了解被序列化的类需要实现 Serializable 接口,使用 ObjectInputStreamObjectOutputStream 进行对象的读写。
四、常出现的情景
1、两个类A B代码完全相同,试图通过网络传递对象数据,A 端将对象 C 序列化为二进制数据再传给 BB 反序列化得到 C。但一直反序列化不成功。

解决:虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID = 1L)。虽然两个类的功能代码完全一致,但是序列化 ID 不同,他们无法相互序列化和反序列化。

序列化 ID 在 Eclipse 下提供了两种生成策略,
(1)固定的 1L(一般这么做。可以确保代码一致时反序列化成功)

private static final long serialVersionUID = 1L;

(2)一个是随机生成一个不重复的 long 类型数据(作用是:通过改变序列化 ID 可以用来限制某些用户的使用。)
2、Facade外观模式:
Client 端通过 Façade Object 才可以与业务逻辑对象进行交互。而客户端的 Façade Object 不能直接由 Client 生成,而是需要 Server 端生成,然后序列化后通过网络将二进制对象数据传给 ClientClient 负责反序列化得到 Façade 对象。

即 服务端(生成Facade object)序列化 ----->客户端(反序列化,得到Facade对象,可用其与业务逻辑对象交互)

该模式可以使得 Client 端程序的使用需要服务器端的许可,同时 Client 端和服务器端的 Façade Object 类需要保持一致。当服务器端想要进行版本更新时,只要将服务器端的 Façade Object 类的序列化 ID 再次生成,当 Client 端反序列化 Façade Object 就会失败,也就是强制 Client 端从服务器端获取最新程序。

3、一个类实现了序列化,并且有其静态变量。
但序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。

4、父类的序列化与transient
父类不实现序列化,子类实现序列化,则将子类对象反序列化后输出父类定义的某变量的数值,该变量数值与序列化时的数值不同。

原因:一个java对象的构造必须先有父对象,再有子对象,反序列化也是,父类没有实现序列化,则虚拟机不会序列化父类。

解决:
a、父类也实现序列化
b、为父类创造默认的无参的构造方法,在父类无参构造方法中对父类进行变量初始化。则反序列化时,构造父对象时只能调用父类无参构造函数为默认父对象,如果不先在无参构造函数中初始化变量,则父类变量值都会是默认声明值,如0,null

所以,使变量不被序列化的方法有:
a、Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null
b、可以将不需要被序列化的字段抽取出来放到父类中,子类实现序列化,父类不实现,则父类的字段数据将不会被序列化。

5、对敏感字段加密
服务端给客户端发送序列化对象数据,并在序列化时进行加密,客户端用解密密钥,在反序列化时,对密码读取,保证了序列化对象的数据安全。

在序列化过程中,虚拟机会试图调用对象类里的 writeObjectreadObject 方法,进行用户自定义的序列化和反序列化,如果没有这样的方法,则默认调用是 ObjectOutputStreamdefaultWriteObject 方法以及 ObjectInputStreamdefaultReadObject 方法。用户自定义的 writeObjectreadObject 方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。基于这个原理,可以在实际应用中得到使用,用于敏感字段的加密工作。

RMI技术。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值