1.Object
使用对象声明 object
object Singleton {
const val a = 1
var b = 2
fun add(): Int {
return a + b
}
}
直接用object代替class修饰类就是单例,对应的java代码就是:
public final class Singleton {
public static final int a = 1;
private static int b;
public static final Singleton INSTANCE;
public final int getB() {
return b;
}
public final void setB(int var1) {
b = var1;
}
public final int add() {
return 1 + b;
}
private Singleton() {
}
static {
Singleton var0 = new Singleton();
INSTANCE = var0;
b = 2;
}
}
这就是典型的饿汉式单例,在类加载的时候就进行了初始化,没有使用懒加载
2.双重验证的方法
由于Kotlin中没有 static关键字,所以静态方法放在companion object{}中
class Singleton private constructor() {
companion object {
@Volatile
private var mInstance: Singleton? = null
val instance: Singleton?
get() {
if (mInstance == null) {
synchronized(Singleton::class.java) {
// if (mInstance == null) {
mInstance = Singleton()
// }
}
}
return mInstance
}
}
}
//Kotlin写法
class SingletonKt private constructor() {
private var a = 1
val b = 2
fun add() = a + b
companion object {
val INSTANCE by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
SingletonKt()
}
}
}
上述代码中,我们可以发现在Kotlin实现中,我们让其主构造函数私有化并自定义了其属性访问器,其余内容大同小异
3.静态内部类
class Singleton private constructor() {
private object SingletonInstance {
val INSTANCE = Singleton()
}
companion object {
val instance: Singleton
get() = SingletonInstance.INSTANCE
}
}
4.双重校验锁式
//Java实现
public class SingletonDemo {
private volatile static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
if(instance==null){
synchronized (SingletonDemo.class){
if(instance==null){
instance=new SingletonDemo();
}
}
}
return instance;
}
}
//Kotlin实现
class Singleton private constructor() {
companion object {
val instance: Singleton by lazy() {
Singleton()
}
}
}
//传递参数
class TestKt1 private constructor(private val property: Int) {
companion object {
@Volatile
private var instance: TestKt1? = null
@JvmStatic
fun getInstance(property: Int) = instance ?: synchronized(this) {
instance ?: TestKt1(property = property).also { instance = it }
}
}
}
Lazy是接受一个 lambda 并返回一个 Lazy 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。