Kotlin hilo seguro singleton perezoso nativo con parámetro
En java podemos escribir los singletons seguros para usar usando el bloqueo doble comprobado y volátil:
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance(String arg) {
Singleton localInstance = instance;
if (localInstance == null) {
synchronized (Singleton.class) {
localInstance = instance;
if (localInstance == null) {
instance = localInstance = new Singleton(arg);
}
}
}
return localInstance;
}
}
¿Cómo podemos escribirlo en Kotlin?
Sobre objetoobject A {
object B {}
object C {}
init {
C.hashCode()
}
}
Usé el descompilador Kotlin para conseguir eso
public final class A {
public static final A INSTANCE;
private A() {
INSTANCE = (A)this;
A.C.INSTANCE.hashCode();
}
static {
new A();
}
public static final class B {
public static final A.B INSTANCE;
private B() {
INSTANCE = (A.B)this;
}
static {
new A.B();
}
}
public static final class C {
public static final A.C INSTANCE;
private C() {
INSTANCE = (A.C)this;
}
static {
new A.C();
}
}
}
Todos los objetos tienen invocación de constructor enstatic
bloquear. En base a esto, podemos pensar que no es perezoso.
class Singleton {
companion object {
val instance: Singleton by lazy(LazyThreadSafetyMode.PUBLICATION) { Singleton() }
}
}
Descompilado:
public static final class Companion {
// $FF: synthetic field
private static final KProperty[] $delegatedProperties = new KProperty[]{(KProperty)Reflection.property1(new PropertyReference1Impl(Reflection.getOrCreateKotlinClass(Singleton.Companion.class), "instance", "getInstance()Lru/example/project/tech/Singleton;"))};
@NotNull
public final Singleton getInstance() {
Lazy var1 = Singleton.instance$delegate;
KProperty var3 = $delegatedProperties[0];
return (Singleton)var1.getValue();
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
Espero que los desarrolladores de Kotlin hagan una implementación sin reflexión en el futuro ...