Realm Any
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>())
}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()) // trueRealmAny 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 propertyRealmAny cannot store EmbeddedRealmObjects.
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 FloatTypes
Functions
Returns the value from this RealmAny as a ByteArray.
Returns the value from this RealmAny as a Decimal128.
Returns the value from this RealmAny as a BsonObjectId.
Returns the value from this RealmAny as a RealmInstant.
Returns the value from this RealmAny as a BaseRealmObject of type T.
Returns the value from this RealmAny as a RealmUUID.
Properties
Extensions
Creates an unmanaged RealmAny instance from a BaseRealmObject value.