Skip to end of metadata
Go to start of metadata

Field accessors in Java

In Java world, we are so accustomed to writing getters and setters for our fields, that the advice by Effective Java Item 14: In public classes, use accessor methods, not public fields sort of goes without saying. All major IDEs help us here: they generate getters and setters, so that it is not that hard to produce a class like this:

Most of the lines in this class are pure boilerplate code.

Getting rid of field/get/set triples

In Kotlin, there's no way to declare a field. All you have is properties. Read/write properties are declared with the var keyword, and read-only ones – with val keyword. Thus, the class above can be rewritten as follows:

public class Address() { // parentheses denote a _primary constructor_ 
  public var name : String = ... 
  public var street String = ... 
  public var city : String = ... 
  public var state : String? = ... 
  public var zip : String = ... 
}
Here we have five mutable properties, each of which has a backing field that stores the value, and two accessors: getter and setter. Thus, the byte-code generated from this class will be almost equivalent to the one for the Java class above. The only difference will be property initializers, see Null-safety.

(For even better option look here).

To use a property, one simply refers to it by name, as if it were a field in Java:

fun copyAddress(address : Address) : Address { 
  val result = Address() // there's no 'new' keyword in Kotlin 
  result.name = address.name // accessors are called 
  result.street = address.street 
  // ... 
  return result 
}

Declaring properties and accessors

The full syntax for a mutable property declaration is as follows:

var <propertyName> : <PropertyType> [= <property_initializer>] 
  <getter> 
  <setter>

The initializer, getter and setter are optional. Property type is optional if it can be inferred from the initializer or from the base class member being overridden .

Examples:

var 
allByDefault
 : Int? // error: explicit initializer required, default getter and setter implied 
var initialized = 1 // has type Int, default getter and setter 
var setterVisibility : String = "abc" // Initializer required, not a nullable type 
  private set // the setter is private and has the default implementation

Note that types are not inferred for properties exposed as parts of the public API, i.e. public and protected, because changing the initializer may cause an unintentional change in the public API then. For example

public val 
example
 = 1 // A public property must have a type specified explicitly

The full syntax of an immutable property declaration differs from a mutable one in two ways: it starts with val instead of var and does not allow a setter:

val simple : Int? // has type Int, default getter, must be initialized in constructor 
val inferredType = 1 // has type Int and a default getter

We can write custom accessors, very much like ordinary functions, right inside a property declaration. Here's an example of a custom getter:

val isEmpty : Boolean 
  get() = this.size == 0

Since this property is purely derived from others, the compiler will not generate a backing field for it.

A custom setter looks like this:

var stringRepresentation : String 
  get() = this.toString() 
  set(value) { 
    setDataFromString(value) // parses the string and assigns values to other properties 
  }

Backing fields

As we mentioned above, some properties have backing fields, i.e. from the client's point of view, a property is a pair of accessors (or just one getter), but physically the accessors may read and write data from/to a real field. One can not declare a field explicitly in Kotlin, the compiler figures it out for us.

In the simple cases, when we do not provide custom accessor implementations, it is obvious that a property must have a backing field, otherwise what should the default accessors do in the following case?

var counter : Int = 0

But when there is a custom accessor, it may or may not rely on a backing field.
To access a backing field of a property x, one says $x (the dollar sign cannot be used as a part of an identifier in Kotlin):

var counter = 0 // the initializer value is written directly to the backing field 
  set(value) { 
    if (value >= 0) 
      $counter = value 
  }

The $counter field can be accessed only from inside the class where the counter property is defined.

The compiler looks at the accessors' bodies, and if they use the backing field (or the accessor implementation is left by default), a backing field is generated, otherwise it is not.

For example, in the following case there will be no backing field:

val isEmpty : Boolean 
  get() = this.size > 0

The backing field is not needed because the only accessor does not refer to it.

What if I want to do ... ?

If you want to do something that does not fit into this "implicit backing field" scheme, you can always fall back to having a "backing property":

private var _table : Map<String, Int>? = null 
public val table : Map<String, Int> 
  get() { 
    if (_table == null) 
      _table = HashMap() // Type parameters are inferred 
    return _table ?: throw AssertionError("Set to null by another thread") 
  }

In all respects, this is just the same as in Java since access to private properties with default getters and setters is optimized so that no function call overhead is introduced.

Overriding properties

See Overriding properties.

Best practices related to this feature

J. Bloch. Effective Java Second Edition
Item 14: In public classes, use accessor methods, not public fields

See also: JavaBeans

Similar features in other languages

Java IDEs generate accessors automatically.

For Java, there's Project Lombok : the syntax for properties is based on Java annotations.

In C#, Groovy Beans and Gosu one still writes getters and setters alongside their backing fields that are declared explicitly, although the access looks like property access. Scala does not distinguish between a field and a property, but to customize a setter one needs to write a separate function named by convention.

What's next

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jul 21, 2011

    Anonymous

    One comment says: "there's no 'new' keyword in Up"

    Was the language once called Up or am I missing something? 

    1. Jul 22, 2011

      Yes. And before that it've been called Jet

    2. Jul 22, 2011

      That comment is fixed. Thanks

  2. Jul 22, 2011

    Anonymous

    That example stretches the semantic of "immutable" too much.

    When i see immutable field, i expect that if i will create a local copy of it that local copy will be always equal to the original field.

    1. Jul 22, 2011

      True. That's why Kotlin doesn't have fields and has properties instead.

  3. Jul 22, 2011

    Will properties be real objects with a literal syntax for looking them up like in Gosu and Fantom?  Or will they just be two methods as in Scala?

    1. Jul 22, 2011

      Both. There's hash syntax, that returns an instance of Property class. Very useful for binding frameworks indeed.

  4. Jul 23, 2011

    Anonymous

    Is there a way to provide public getters only? Think of fields that should be readable by anyone (public) but
    you want to keep control over its modifications (so private/protected for writing).

    For example, to keep some invariants or to do some further actions upon modifications.
    This is a feature I am missing in other languages a lot.

    1. Jul 23, 2011

      There's an example above. Basically, you say

      var foo : Int 
        get 
        private set

      Also, the accessors can have bodies.

      1. Jul 23, 2011

        Anonymous

        Oh, I missed that when reading the example. Awesome!

  5. Jul 23, 2011

    Anonymous

    I'm a bit disappointed that Kotlin seems to be perpetuating one of what I consider to be Java's worst subtle design mistakes: It is making the default modifier for variables (or in the case of Kotlin, properties) be effectively 'public' instead of 'private'.

    New programmers often get into the very bad habit of relying on the default modifier because it happens, well, "by default", and also because it involves less typing. In reviewing others' Java code, I frequently find that lots of variables (and methods) are declared with Java's default "package access" even though they have absolutely no legitimate reason to be accessed by anything except for the class that declares them. They are declared accessible to the entire rest of the package that contains that class, and to all subclasses, for no good reason other than programmer laziness and the fact that Java makes everything visible to the entire package that declares it and to all subclasses unless specified otherwise.

    The usual consequence of this over the long term is that eventually other programmers end up relying on having direct access to that class's unnecessarily public internal data.. The programmers who write that outside code should instead have requested that the class have appropriate interface functions added to it that would do more specifically what the outside code needs to do. The typical name for the resulting problem is "feature envy": code outside of a class that looks like this:

    instead of looking like this:

    I recognize that the fact that Kotlin provides properties rather than public fields makes this a bit less painful than it is in Java, since the property definitions can be modified later to not actually keep the data in an actual backing field without forcing the code that calls it to change. However, the basic problem still remains: The fact that properties are not 'private' by default means that users will almost certainly end up making many classes' internal data public without really thinking about whether that data SHOULD be public. It also encourages programmers to think of a class's interface in terms of what properties it has rather than thinking in terms of what operations should be defined on it (based on what things need to be done together as atomic operations).

    I would much prefer that by default, a class's data be implicitly 'private', so that a user has to make a conscious decision to expose a property to the outside world by adding the 'public' keyword, rather than vice versa. (I am pretty sure that Effective Java has a section on keeping data private when possible.)

    A similar argument applies to methods, of course, but in that case it's a bit less critical since the majority of methods are created to provide an interface for accessing data, and so are public anyway.

    In summary: Most fields should be private, and most methods should be protected or public, so it would be helpful if the language set its defaults that way to help encourage people to write maintainable code.

    1. Jul 24, 2011

      There are tradeoffs here. We decided to make internal, which is "private to the current module" to be the default.

      Also note that properties are not fields.

      1. Aug 14, 2011

        Anonymous

        What specific tradeoffs motivated you to make "private to the current module" be the default?

        That seems like it exposes quite a bit of data unnecessarily. Most OO gurus (Booch, etc.) suggest making things (methods, fields) as private as possible until it is demonstrated that they need to be more public. This is to avoid maintenance problems where outside code depends on the internals of a class instead of its interface, and then those internals change. Admittedly, this problem is lessened if only outside code located in the current module has access, but even so it is still a real concern. I have not-uncommonly seen packages with fifty classes in them. Presumably ALL of those shouldn't have access to each other's internals.

        1. Aug 14, 2011

          Analysis of Java codebases shows that the majority of the methods there are public. This is what made Scala have public by default. The default is internal in Kotlin, because we believe that this covers most of the cases where Java programmers had to say public.

  6. Aug 01, 2011

    Anonymous

    How come the following wouldn't work

    1. Aug 02, 2011

      val means that the backing field $table is final.

  7. Aug 17, 2011

    Anonymous

    Does the property object returned by the hash syntax support change listeners?  And is there an example of the hash syntax?

    Cheers

    1. Aug 17, 2011

      Here's the syntax example:

      val prop = a#foo

      The reflection API is not designed yet, but your request for change listeners sounds very sensible.

      1. Aug 17, 2011

        Change listeners would be great.  Has any though been given to property paths in a style like Apple's key value coding?  When doing binding in a UI context I often want to be able to specify a property path in the absence of the bean.

        Also does the syntax support nested properties?  e.g. val prop = a#b#c 

        1. Aug 17, 2011

          You can say C#p1#p2#p2 for a property path starting with an object of class C

          1. Aug 18, 2011

            Cool, so if 

            gives me a Property<TypeOfC>, what does

            give me?  And how can I use it given a specific instance of A?

            1. Aug 18, 2011

              a#b#c gives you a property object that you can read from/write to, and
              A#b#c give you an extension property object that you can call on instances of A:

              val a : A = ... 
              a.whatsthis = 5
              1. Aug 19, 2011

                Do you have any other info on extension properties?  Or is it just an extension function that fetches a property for a given object?

                1. Aug 19, 2011

                  It's like a pair of extension functions (for get and set) that read/write a property, nothing more.

                  1. Aug 20, 2011

                    Ok, I presume by property you mean the value T and not the Property<T>?  

                    I'm also looking at it from the perspective of writing event driven binding libraries, and one thing I've always wanted is the notion of a property path as a fully fledged type.  Generally this is because I've created bindings once during construction and had the paths track the values as the beans come and go or as they are mutated.  For example I need to be able to track changes to parent properties so if some one invokes `a.b = B()` then fields bound to A#b#c would then update appropriately.  Hence if I'm some binds A#b#c I need to find the path A#b from it.

                    I played around a bit with Bindgen and it has a path style type notion under the hood.  Internally it implements this using a couple of standard interfaces and code generation that creates a bunch of concrete inner classes for all the bindings  (it's been a while since I've played with Bindgen so hopefully I'm not way off key with that summary).  There's a lot of work under the hood but you get some pretty nice code completion and type safety.

                    I guess what I'm aiming for is something like:

                    Where I can use a path to get a property.  e.g. 

                    Cheers

                    1. Aug 20, 2011

                      Thanks for the explanation. I think it's a nice capability.

  8. Aug 19, 2011

    As always, two nice-to-have features of properties are as follows:

    1. Having support for lazy initialization. For example, in C#, we write
      Lazy<Foo> foo = new Lazy<Foo>(() => new Foo());
      

      but it would be great for Kotlin to have even neater syntax such as

      lazy var foo = Foo()
      
    2. Another interesting feature that we on the .Net side really want is change notification right inside the property - something along the lines of
      var foo : Int
        get
        set
        notify
      

      In actual fact, what would be interesting is some kind of meta-AOP approach, such that instead of writing get, set, and so on, we could completely supplant the language's default way of implementing properties with one of our own. Or does Kotlin support this already?

    1. Aug 19, 2011

      1. We plan to have it as a compiler extension. There are some things to think about here, though, i.e. how this lazy thing is synchronized...

      2. Sounds like a source for a lot of mysterious bugs.

      1. Apr 25, 2012

        Really common C# lazy properties pattern:

  9. Aug 19, 2011

    Would it be possible to support properties for immutable objects where the setter returns an updated copy of the object?  It would be even better if this could be combined with property paths to allow "updating" deeply nested immutable objects.

    1. Aug 19, 2011

      Well, I can't imagine a syntactic form for that.

      What we are planning to have is auto-generated copy-methods, so that, if you want to update your immutable object and get a copy, you say

      val newObj = obj.copy( 
                     prop = value 
                   )
      1. Aug 19, 2011

        One of the main advantages of first class properties is that it allows simple meta-programming, e.g. in binding frameworks.  Would that be possible with the proposed copy() method?  Would there be a way to invoke copy() without explicitly referring to the argument names?

        If this isn't possible with the copy() method it would be impossible to use immutable objects in certain situations and that would be a shame.

        1. Aug 19, 2011

          Could you describe the use case you have in mind?

          1. Aug 19, 2011

            I think it would be useful wherever you want to bind property values and update them. Let's say I was writing a Wicket application and I wanted to create a page to update an object. I would implement the IModel interface to wrap a property and pass an instance of the model to each form object.

            For a mutable class the model implementation would look like this:

            class MutablePropertyModel<T>(prop : Property<T>) : IModel<T> { 
             
              fun getObject() : T { 
                return prop.get() 
              } 
             
              fun setObject(newValue : T) { 
                prop.set(newValue) 
              } 
            }

            For an immutable class with setters that return an updated object the model implementation would be something like:

            // U is the type of the model object that owns the property 
            // ref holds the model object - ref is obviously necessary because the object can't be updated 
            class ImmutablePropertyModel<T, U>(prop : ImmutableProperty<T, U>, ref : AtomicReference<U>) : IModel<T> { 
             
              fun getObject() : T { 
                return prop.get() 
              } 
             
              fun setObject(newValue : T) { 
                ref.set(prop.set(newValue)) 
              } 
            }

            I've done something very similar in Clojure where the model object was an immutable map. Is there a way to implement something like this using the copy() method?

            Another obvious example is setting an object's state some other format. e.g. some properties

            var foo = Foo() 
            // for each property 
              val propName = ... 
              val propValue = ... 
              val prop = foo.property(propName) // get the property by name 
              foo = prop.set(propValue)
            1. Sep 02, 2011

              Thanks

  10. Oct 17, 2011

    I have a couple questions.

    1. A val property has a final backing field. That fact, combined with the meaning of val when used with local variables, implies to me that such a property should always return the same object (you also describe it as an "immutable property"). That is not the case, though, as the property's get method can return anything. One of the examples above shows a property that will change values as other properties change:

    A val property could in fact be fully mutable, by just delegating get to return the value of a separate var property in the class. This seems confusing. I guess this isn't really a question, but I was wondering about your thoughts on that.

    2. The second question relates to this example:

    In this example, clearly we would like the type of table to be Map<String, Int> rather than Map<String, Int>?. I believe I saw the same example elsewhere in this wiki except using the non-nullable type for table.

    The implementation of get() certainly appears to ensure it's returning a non-null value, but what if there were another method that could set _table to null? If that happened on another thread, _table could be null when get() returns it. It seems like the compiler would need to know there were no potential concurrency issues like that to be able to guarantee the property's type of Map<String, Int>. Has there been any consideration of that sort of thing?

    1. Oct 17, 2011

      1. I agree that it's not fully correct to describe val as an immutable property. It is actually a property that can not be assigned to (mutated directly).
      2. This is a mistake in the example. It would not compile unless we say something like

      return _table ?: throw AssertionError()

      Thank you for pointing these things out, I'll fix them in the text

      1. Oct 25, 2011

        Anonymous

        If you are going to do that, wouldn't you want to declare the public property as "publicvaltable:Map<String,Int>" instead of "publicvaltable:Map<String,Int>?"? Otherwise, the method is declared as nullable even though it can never return null.

        You could also simplify to "throw _table.npe();"

        1. Oct 25, 2011

          Oh, thank you so much for noticing, I sincerely believed I made the public one non-null.

          On the .npe(): I don't use it here for the text to be easier to understand.

  11. Feb 16, 2012

    It seems documentation is bit outdated, since code:

    in web demo fail with errors:

    1. Feb 16, 2012

      Fixed, thanks

      1. Feb 16, 2012

        And example in section below(Declaring properties and accessors) with code:

        need to be fixed

  12. Apr 24, 2012

    causes deadly recursion. It is a mistake, I forgot to put $. Rather common mistake remembering my properties experience in C#.

    i think it will be really usefull to permit accessing property in it's getter o setter, only accessing accessor is aloud.

    for some cases where somebody need to call get() inside get() (me, personaly, can't imagine such a case) there should be some

    special syntax like 

    get() = get()
    

    or

    get() = $x.get()
    

    which will replace

    get() = x
    
    1. Apr 24, 2012

      Your concern is valid, indeed.

      get() = get()

      Looks too weird, and wouldn't work, because there may be a normal function called get().

      get() = $x.get()

      is ambiguous: $x may be, for example, of type List and have a member function get().

      1. Apr 25, 2012

        I thout a bit on workaround. I can not imagine any usecase when recursion is needed. Is there any one in your code base?

        I see two options:

        1. Just permit. Property is the thing you get or set, but do not count. If you want fancy logic -- use function instead. (You also can write recursive function and use it inside getter).
        2. As it is in null safety, when you are going to write some unsafe code, you use "!!", so the sintax can be like
        var x : Int
        get() = !!x;
        
        1. Apr 25, 2012

          Recursion is unlikely to be needed. Feel free to file an issue about prohibiting recursion in getters.

          The second suggestion will be confusing, because !!x looks like double negation.

          1. Apr 25, 2012

            Wonder how C# code like this will looks like in Kotlin?

            1. Apr 25, 2012

              class Foo { 
                public open val value : Int 
                  get() = ... 
              } 
               
              class Bar : Foo() { 
                override val value : Int 
                  get() = super.value + 42 
              }
  13. Jul 05, 2012

    Why can't I have property without get and init value? like this:

    var property: Type 
        set(value) = doSomething(value)
    1. Jul 06, 2012

      The rule is that if a getter or a setter is not present, it is implemented by default: i.e. by using a backing field. A backing field demands initialization

  14. Jul 12, 2012

    Very good work and there is a lot of things that I like in C# and Scala here... but one more question about the properties.

    The Kotlin compiler generates for each readable and writable property a get/set pair of methods... so far so good!

    But why not to make the inverse valid? When using some Java class with a get and set property, like getName() and setName(String name),

    why not allow to omit the get and set prefixes, just like the groovy (ie. val a = javaObject.name)?

    1. Jul 13, 2012

      Thanks for the kind words.

      About the feature you are requesting: there are quite a few subtleties about this. The biggest difference from Groovy is that Kotlin is statically typed, so we have to handle everything rigorously. Example: what if you have inherited both name() and getName() from somewhere? How is that supposed to work?

      We will do something about it, but I'm not yet sure how much can be done with no user interference.

      1. Sep 13, 2012

        I got it! Thanks for the explanation! That kind of situation will be hard to do something...

      2. Dec 30, 2012

        I was thinking in just a convention, as the others used by kotlin... if is a get method with no parameters than that is a property accessor... the same way could be done to the setter.

        I am talking about this because most of the time we will use other libraries and frameworks... And sometimes we will write "getX()" others just "x"... and in the final bytecode, both methods will be get accessors.

        1. Jan 09, 2013

          Unfortunately, this convention gets weird when inheritance is involved.

  15. Sep 18, 2012

    а кто знает как можно вырубить эти геттеры и сеттеры к черту? а то я уже устал искать ошибки из за них. Простой пример под андроидом: 
    var transactionManager : TransactionManager? = null
    onCreate (....){
    ....
    transactionManager = getTransactionManager()
    }

    Так вот, getTransactionManager() возвращал всегда null, потому что, видите ли, сомпилятор думает что я обращаюсь к полю своего класса. А я пытаюсь вызвать метод класса предка. Не писать же везде super<Activity>.getTransactionManager() ? Вся фишка простоты котлина пропадает.

    1. Sep 18, 2012

      Мы, со временем, будем генерировать сообщение об ошибке в этой ситуации.
      Напишите нам реквест в трекер.

  16. Dec 29, 2012

    How do I define a get()/set() pair of methods for constructor properties?

    My guess

    does not compile.

    1. Jan 09, 2013

      You can not specify custom accessors in the primary constructor. Use simple constructor parameters + full property declarations in the class body:

      class User2(name: String) { 
        val name: String 
          get() = "hugo" 
      }
  17. Oct 15, 2013

    Link to Effective Java leads to main java oracle page.

    1. Oct 15, 2013

      Fixed. Thanks!