Java性能 -- 原型模式 + 享元模式
原型模式
- 原型模式:通过给出一个原型对象来指明所创建的对象的类型,然后使用自身实现的克隆接口来复制这个原型对象
- 使用这种方式创新的对象的话,就无需再通过new实例化来创建对象了
- Object类的clone方法是一个Native方法,可以直接操作内存中的二进制流,所以相对new实例化来说,性能更佳
实现原型模式
1 | class Prototype implements Cloneable { |
- 实现
Cloneable
接口- Cloneable接口与Serializable接口的作用类似,告诉JVM可以安全地在实现了Cloneable接口的类上使用clone方法
- 在JVM中,只有实现了Cloneable接口的类才可以被拷贝,否则会抛出
CloneNotSupportedException
- 重写Object类的
clone
方法- Object类中有一个clone方法,作用是返回对象的一个拷贝
- 在重写的clone方法中调用**
super.clone()
**,因为默认情况下,_类不具备复制对象的能力_
- 通过clone方法复制的对象是真正的对象复制,clone方法复制的对象是一个完全独立的对象
- Object类的clone方法是一个Native方法,直接操作内存的二进制流,特别是复制大对象时,性能的差别特别明显
1 |
|
深拷贝 / 浅拷贝
- 在调用
super.clone()
方法后,首先会检查当前对象所属的类是否支持clone,即看该类是否实现了Cloneable
接口 - 如果支持,则创建当前对象所属类的一个新对象,并对该对象进行初始化
- 使得新对象的成员变量的值与当前对象的成员变量的值一模一样
- 但对于其它对象的引用以及List等类型的成员属性,则只能复制这些对象的引用
- 所以调用
super.clone()
的克隆对象方式,是一种浅拷贝
- 深拷贝其实就是基于浅拷贝来递归实现具体的每个对象
浅拷贝
1 | // 浅拷贝 |
深拷贝
1 |
|
适用场景
- 在一些重复创建对象的场景下,可以使用原型模式来提供对象的创建性能
- Spring中的
@Service("prototype")
享元模式
- 享元模式是运用共享技术有效地最大限度地复用细粒度对象的一种模式
- 在享元模式中,以对象的信息状态划分,可以分为内部数据和外部数据
- 内部数据是对象可以共享出来的信息,这些信息不会随着系统的运行而改变
- 外部数据则是在不同运行时被标记了不同的值
- 享元模式一般分为三个角色
- Flyweight(抽象享元类):通常是一个接口或抽象类,向外界提供享元对象的内部数据或外部数据
- ConcreteFlyweight(具体享元类):实现内部数据共享的类
- FlyweightFactory(享元工厂类):创建和管理享元对象的工厂类
实现享元模式
Flyweight
1 | interface Flyweight { |
ConcreteFlyweight
1 |
|
FlyweightFactory
1 | class FlyweightFactory { |
Client
1 | public class Client { |
适用场景
- Java中的String,在一些字符串常量中,会共享常量池中字符串对象,从而减少重复创建相同值对象,减少空间占用
- 线程池和Java本地缓存也是享元模式的一种实现
1 | String s1 = "hello"; |
参考资料
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.