[toc]
手写单例模式
饿汉模式
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
优点是线程安全的,只有一个实例。缺点是即使没有调用getInstance()方法,instance实例在类加载时被初始化了。
双重检查锁模式,非线程安全
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
装饰器模式
代理模式 (静态、动态)
静态代理:需要代理对象和目标对象实现一样的接口。 缺点:
- 冗余。由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。
- 不易维护。一旦接口增加方法,目标对象与代理对象都要进行修改。
动态代理: 动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。
静态代理与动态代理的区别主要在:
- 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件
- 动态代理是在运行时动态生成的,即编译完成后没有实际的 class 文件,而是在运行时动态生成类字节码,并加载到 JVM中
JDK 动态代理和 cglib 代理: 1、Jdk 动态代理:利用拦截器(必须实现 InvocationHandler 接口)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用 InvokeHandler 来处理 2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来进行代理
cglib 与 JDK 动态代理最大的区别就是
- 使用动态代理的对象必须实现一个或多个接口
- 使用 cglib 代理的对象则无需实现接口,达到代理类无侵入。
工厂模式
适配器模式
策略模式
Java 库、中间件等用了哪些设计模式
oop - Examples of GoF Design Patterns in Java’s core libraries - Stack Overflow
工厂模式:Calendar
原型:Object.Clone
装饰者:Collections#synchronizedxxx()
享元:Integer#valueOf()
策略模式:Comparator#compare()