Lazy made serializable.
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package kotlin
|
package kotlin
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a value with lazy initialization.
|
* Represents a value with lazy initialization.
|
||||||
@@ -40,11 +42,11 @@ public enum class LazyThreadSafetyMode {
|
|||||||
|
|
||||||
private object UNINITIALIZED_VALUE
|
private object UNINITIALIZED_VALUE
|
||||||
|
|
||||||
private class LazyImpl<out T>(initializer: () -> T) : Lazy<T> {
|
private class LazyImpl<out T>(initializer: () -> T) : Lazy<T>, Serializable {
|
||||||
private var initializer: (() -> T)? = initializer
|
private var initializer: (() -> T)? = initializer
|
||||||
private volatile var _value: Any? = UNINITIALIZED_VALUE
|
private volatile var _value: Any? = UNINITIALIZED_VALUE
|
||||||
|
|
||||||
public override val value: T
|
override val value: T
|
||||||
get() {
|
get() {
|
||||||
val _v1 = _value
|
val _v1 = _value
|
||||||
if (_v1 !== UNINITIALIZED_VALUE) {
|
if (_v1 !== UNINITIALIZED_VALUE) {
|
||||||
@@ -65,16 +67,16 @@ private class LazyImpl<out T>(initializer: () -> T) : Lazy<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val valueCreated: Boolean = _value !== UNINITIALIZED_VALUE
|
override val valueCreated: Boolean get() = _value !== UNINITIALIZED_VALUE
|
||||||
|
|
||||||
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not initialized yet."
|
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not initialized yet."
|
||||||
|
|
||||||
|
private fun writeReplace(): Any = InitializedLazyImpl(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class UnsafeLazyImpl<out T>(initializer: () -> T) : Lazy<T> {
|
private class UnsafeLazyImpl<out T>(initializer: () -> T) : Lazy<T>, Serializable {
|
||||||
private var initializer: (() -> T)? = initializer
|
private var initializer: (() -> T)? = initializer
|
||||||
|
|
||||||
|
|
||||||
private var _value: Any? = UNINITIALIZED_VALUE
|
private var _value: Any? = UNINITIALIZED_VALUE
|
||||||
|
|
||||||
override val value: T
|
override val value: T
|
||||||
@@ -86,7 +88,17 @@ private class UnsafeLazyImpl<out T>(initializer: () -> T) : Lazy<T> {
|
|||||||
return _value as T
|
return _value as T
|
||||||
}
|
}
|
||||||
|
|
||||||
override val valueCreated: Boolean = _value !== UNINITIALIZED_VALUE
|
override val valueCreated: Boolean get() = _value !== UNINITIALIZED_VALUE
|
||||||
|
|
||||||
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not initialized yet."
|
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not initialized yet."
|
||||||
|
|
||||||
|
private fun writeReplace(): Any = InitializedLazyImpl(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InitializedLazyImpl<out T>(override val value: T) : Lazy<T>, Serializable {
|
||||||
|
|
||||||
|
override val valueCreated: Boolean get() = true
|
||||||
|
|
||||||
|
override fun toString(): String = value.toString()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,19 +154,23 @@ class CollectionJVMTest {
|
|||||||
test fun emptyMapIsSerializable() = testSingletonSerialization(emptyMap<Any, Any>())
|
test fun emptyMapIsSerializable() = testSingletonSerialization(emptyMap<Any, Any>())
|
||||||
|
|
||||||
private fun testSingletonSerialization(value: Any) {
|
private fun testSingletonSerialization(value: Any) {
|
||||||
val outputStream = ByteArrayOutputStream()
|
val result = serializeAndDeserialize(value)
|
||||||
val objectOuputStream = ObjectOutputStream(outputStream)
|
|
||||||
|
|
||||||
objectOuputStream.writeObject(value)
|
assertEquals(value, result)
|
||||||
objectOuputStream.close()
|
assertTrue(value === result)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun serializeAndDeserialize<T>(value: T): T {
|
||||||
|
val outputStream = ByteArrayOutputStream()
|
||||||
|
val objectOutputStream = ObjectOutputStream(outputStream)
|
||||||
|
|
||||||
|
objectOutputStream.writeObject(value)
|
||||||
|
objectOutputStream.close()
|
||||||
outputStream.close()
|
outputStream.close()
|
||||||
|
|
||||||
val inputStream = ByteArrayInputStream(outputStream.toByteArray())
|
val inputStream = ByteArrayInputStream(outputStream.toByteArray())
|
||||||
val inputObjectStream = ObjectInputStream(inputStream)
|
val inputObjectStream = ObjectInputStream(inputStream)
|
||||||
val result = inputObjectStream.readObject()
|
return inputObjectStream.readObject() as T
|
||||||
|
|
||||||
assertEquals(value, result)
|
|
||||||
assertTrue(value === result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package test.utils
|
||||||
|
|
||||||
|
|
||||||
|
import kotlin.*
|
||||||
|
import kotlin.test.*
|
||||||
|
import java.io.*
|
||||||
|
import org.junit.Test as test
|
||||||
|
|
||||||
|
class LazyJVMTest {
|
||||||
|
|
||||||
|
test fun lazyInitializationForcedOnSerialization() {
|
||||||
|
for(mode in listOf(LazyThreadSafetyMode.SYNCHRONIZED, LazyThreadSafetyMode.NONE)) {
|
||||||
|
val lazy = lazy(mode) { "initialized" }
|
||||||
|
assertFalse(lazy.valueCreated)
|
||||||
|
val lazy2 = serializeAndDeserialize(lazy)
|
||||||
|
assertTrue(lazy.valueCreated)
|
||||||
|
assertTrue(lazy2.valueCreated)
|
||||||
|
assertEquals(lazy.value, lazy2.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun serializeAndDeserialize<T>(value: T): T {
|
||||||
|
val outputStream = ByteArrayOutputStream()
|
||||||
|
val objectOutputStream = ObjectOutputStream(outputStream)
|
||||||
|
|
||||||
|
objectOutputStream.writeObject(value)
|
||||||
|
objectOutputStream.close()
|
||||||
|
outputStream.close()
|
||||||
|
|
||||||
|
val inputStream = ByteArrayInputStream(outputStream.toByteArray())
|
||||||
|
val inputObjectStream = ObjectInputStream(inputStream)
|
||||||
|
return inputObjectStream.readObject() as T
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package test.utils
|
||||||
|
|
||||||
|
import kotlin.*
|
||||||
|
import kotlin.test.*
|
||||||
|
import org.junit.Test as test
|
||||||
|
|
||||||
|
class LazyTest {
|
||||||
|
|
||||||
|
test fun initializationCalledOnce() {
|
||||||
|
var callCount = 0
|
||||||
|
val lazyInt = lazy { ++callCount }
|
||||||
|
|
||||||
|
assertEquals(0, callCount)
|
||||||
|
assertEquals(1, lazyInt.value)
|
||||||
|
assertEquals(1, callCount)
|
||||||
|
|
||||||
|
lazyInt.value
|
||||||
|
assertEquals(1, callCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
test fun valueCreated() {
|
||||||
|
var callCount = 0
|
||||||
|
val lazyInt = lazy { ++callCount }
|
||||||
|
|
||||||
|
assertFalse(lazyInt.valueCreated)
|
||||||
|
assertEquals(0, callCount)
|
||||||
|
|
||||||
|
lazyInt.value
|
||||||
|
|
||||||
|
assertTrue(lazyInt.valueCreated)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test fun lazyToString() {
|
||||||
|
var callCount = 0
|
||||||
|
val lazyInt = lazy { ++callCount }
|
||||||
|
|
||||||
|
assertNotEquals("1", lazyInt.toString())
|
||||||
|
assertEquals(0, callCount)
|
||||||
|
|
||||||
|
assertEquals(1, lazyInt.value)
|
||||||
|
assertEquals("1", lazyInt.toString())
|
||||||
|
assertEquals(1, callCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user