RealmAny

interface RealmAny

RealmAny is used to represent a polymorphic Realm value.

At any particular moment an instance of this class stores a definite value of a definite type. If, for instance, that is a Double value, you may call asDouble to extract that value. You may call type to discover what type of value is currently stored. Calling asDouble on an instance that does not store a Double value would raise an IllegalStateException.

RealmAny behaves like a value type on all the supported types except on Realm objects. It means that Realm will not persist any change to the actual RealmAny value. If a RealmAny holds a RealmObject, it just holds the reference to it, not a copy of the object. Because RealmAny instances are immutable, a new instance is needed to update a RealmAny attribute.

    anObject.realmAnyField = RealmAny.create(42.0)
anObject.realmAnyField = RealmAny.create("Hello")
anObject.realmAnyField = RealmAny.create(MyRealmObject())

It is crucial to understand that the act of extracting a value of a particular type requires definite knowledge about the stored type. Calling a getter method for any particular type that is not the same type as the stored value, results in an exception being thrown.

Our recommendation to handle the RealmAny polymorphism is to write a conditional expression with when around the RealmAny type and its inner value class.

    val realmAny = anObject.realmAnyField
when (realmAny.type) {
INT -> doSomething(realmAny.asInt()) // or as any other primitive derived from 'Number'
BOOLEAN -> doSomething(realmAny.asBoolean())
STRING -> doSomething(realmAny.asString())
BYTE_ARRAY -> doSomething(realmAny.asByteArray())
REALM_INSTANT -> doSomething(realmAny.asRealmInstant())
FLOAT -> doSomething(realmAny.asFloat())
DOUBLE -> doSomething(realmAny.asDouble())
OBJECT_ID -> doSomething(realmAny.asObjectId())
REALM_UUID -> doSomething(realmAny.asRealmUUID())
REALM_OBJECT -> doSomething(realmAny.asRealmObject<MyRealmObject>())
LIST -> doSomething(realmAny.asList())
DICTIONARY -> doSomething(realmAny.asDictionary())
}

Short, Int, Byte, Char and Long values are converted internally to int64_t values. One has to be aware of this when comparing RealmAny values generated from different numeral types, for example:

    RealmAny.create(42.toShort()) == RealmAny.create(42.toByte()) // true

RealmAny cannot store null values, although RealmAny properties must be declared nullable:

    class Warehouse {
var nonNullableStorage: RealmAny = RealmAny.create("invalid") // This is NOT allowed
var nullableStorage: RealmAny? = RealmAny.create("valid") // Property MUST be nullable
var defaultNullStorage: RealmAny? = null // Property MUST be nullable
}

warehouse.nullableStorage = RealmAny.create(22)
warehouse.nullableStorage = null // Assign null directly to the property

RealmAny cannot store EmbeddedRealmObjects.

RealmAny can contain other RealmList and RealmDictionary of RealmAny. This means that you can build nested collections inside a RealmAny-field.

realmObject.realmAnyField = realmAnyListOf(
// Primitive values can be added in collections
1,
// Lists and dictionaries can contain other nested collection types
realmListOf(
realmListOf(),
realmDictionaryOf()
),
realmDictionaryOf(
"key1" to realmListOf(),
"key2" to realmDictionaryOf())
)

DynamicRealmObjects and DynamicMutableRealmObjects can be used inside RealmAny with the corresponding create function for DynamicRealmObjects and with asRealmObject using either DynamicRealmObject or DynamicMutableRealmObject as the generic parameter.

RealmAny values can be sorted. The sorting order used between different RealmAny types, from lowest to highest, is:

  • Boolean

  • Byte/Short/Integer/Long/Float/Double/Decimal128

  • byte[]/String

  • Date

  • ObjectId

  • UUID

  • RealmObject

RealmAny properties can be aggregated. RealmQuery.max and RealmQuery.min produce results based the sorting criteria mentioned above and thus the output type will be a RealmAny instance containing the corresponding polymorphic value. RealmQuery.sum computes the sum of all numerical values, ignoring other data types, and returns a Decimal128 result - SUMs cannot be typed-coerced, that is, queries like this are not allowed:

    realm.query<Warehouse>()
.sum<Float>("nullableStorage") // type CANNOT be coerced to Float

Types

Link copied to clipboard
object Companion
Link copied to clipboard

Supported Realm data types that can be stored in a RealmAny instance.

Properties

Link copied to clipboard
abstract val type: RealmAny.Type

Returns the Type of the RealmAny instance.

Functions

Link copied to clipboard
abstract fun asBoolean(): Boolean

Returns the value from this RealmAny as a Boolean.

Link copied to clipboard
abstract fun asByte(): Byte

Returns the value from this RealmAny as a Byte. RealmAny instances created using Short, Int, Byte, Char or Long values can be converted to any of these types safely, although overflow might occur, for example, if the value to be output as a Short is greater than Byte.MAX_VALUE.

Link copied to clipboard
abstract fun asByteArray(): ByteArray

Returns the value from this RealmAny as a ByteArray.

Link copied to clipboard
abstract fun asChar(): Char

Returns the value from this RealmAny as a Char. RealmAny instances created using Short, Int, Byte, Char or Long values can be converted to any of these types safely, although overflow might occur, for example, if the value to be output as a Short is greater than Char.MAX_VALUE.

Link copied to clipboard
abstract fun asDecimal128(): Decimal128

Returns the value from this RealmAny as a Decimal128.

Link copied to clipboard

Returns the value from this RealmAny as a RealmDictionary containing new RealmAnys.

Link copied to clipboard
abstract fun asDouble(): Double

Returns the value from this RealmAny as a Double.

Link copied to clipboard
abstract fun asFloat(): Float

Returns the value from this RealmAny as a Float.

Link copied to clipboard
abstract fun asInt(): Int

Returns the value from this RealmAny as an Int. RealmAny instances created using Short, Int, Byte, Char or Long values can be converted to any of these types safely, although overflow might occur, for example, if the value to be output as a Short is greater than Int.MAX_VALUE.

Link copied to clipboard
abstract fun asList(): RealmList<RealmAny?>

Returns the value from this RealmAny as a RealmList containing new RealmAnys.

Link copied to clipboard
abstract fun asLong(): Long

Returns the value from this RealmAny as a Long. RealmAny instances created using Short, Int, Byte, Char or Long values can be converted to any of these types safely.

Link copied to clipboard
abstract fun asObjectId(): BsonObjectId

Returns the value from this RealmAny as a BsonObjectId.

Link copied to clipboard

Returns the value from this RealmAny as a RealmInstant.

Link copied to clipboard
abstract fun <T : BaseRealmObject> asRealmObject(clazz: KClass<T>): T

Returns the value from this RealmAny as a BaseRealmObject of type T.

Link copied to clipboard

Creates an unmanaged RealmAny instance from a BaseRealmObject value.

Link copied to clipboard
abstract fun asRealmUUID(): RealmUUID

Returns the value from this RealmAny as a RealmUUID.

Link copied to clipboard
abstract fun asShort(): Short

Returns the value from this RealmAny as a Short. RealmAny instances created using Short, Int, Byte, Char or Long values can be converted to any of these types safely, although overflow might occur, for example, if the value to be output as a Short is greater than Short.MAX_VALUE.

Link copied to clipboard
abstract fun asString(): String

Returns the value from this RealmAny as a String.

Link copied to clipboard
abstract operator override fun equals(other: Any?): Boolean

Two RealmAny instances are equal if and only if their types and contents are the equal.

Link copied to clipboard
abstract override fun hashCode(): Int