Home » Android » android – Does Realm models actually require getters and setters?

android – Does Realm models actually require getters and setters?

Posted by: admin May 14, 2020 Leave a comment


I cannot find it clearly documented anywhere if getters and setters are actually required for fields in a Realm Model. For example, the documentation at https://realm.io/docs/java/latest/api/io/realm/RealmObject.html says

The only restriction a RealmObject has is that fields are not allowed
to be final, transient’ or volatile. Any method as well as public
fields are allowed. When providing custom constructors, a public
constructor with no arguments must be declared and be empty.

Fields annotated with Ignore don’t have these restrictions and don’t
require either a getter or setter.

Which seems to hint that it is required with getters and setters for non-ignored fields. Yet, the documentation at https://realm.io/docs/java/latest/#customizing-objects says

It is possible to use RealmObjects almost like POJOs. Extending from
RealmObject, you can let the fields be public, and use simple
assignments instead of setters and getter.

and then show the code for a Realm Model that does not have any getters and setters and instead have public fields we should use. Really? I thought Realm didn’t even store any values in the actual fields, so reading and writing from them is probably a bad idea? I mean their debugging docs https://realm.io/docs/java/latest/#debugging state:

Unfortunately these values are wrong because the field values are not
used. Realm creates a proxy object behind the scenes and overrides the
getters and setters in order to access the persisted data in the Realm

So could someone please enlighten me? Can I skip getters and setters and just stick with public fields? Is there any thorough docs on this?

How to&Answers:

public fields work in most cases, and since Realm 2.0.0 they work even in constructors of RealmObjects (allowing “default values”), and work if you directly access the property.

For example,

SomeObject obj = results.get(i);
obj.blah = "Blahblah";

That works, because managed RealmObjects’ field access are transformed by the Realm-Transformer into proxy getter/setter calls (in this case, into the realmSet$blah method).

This has been the case since 0.88.0, when Realm started being provided as a Gradle plugin.

However, a major limitation is that the proxy field access doesn’t run in instrumentation tests, because the androidTestCompile scope does not run the transformer.