How to rename a property's backing field in Kotlin

1.6k views Asked by At

EDIT (again): If anyone is interested, you can follow this issue on the tracker.


EDIT: I know about backing properties and that they will cover most use cases. I'm not looking for a work around, I'm specifically looking if there is a way to name the backing field.


You can easily rename the getter and setter of a property like so

@get:JvmName("getFancy")
@set:JvmName("setFancy")
var fancyProperty = ...

But I can't figure out how to change the name of a backing field, even using the @field target.

@field:JvmName("fancy")
var fancyProperty = ...

The above give an error:

This annotation is not applicable to target 'member property with backing field' and use site target '@field'


Ultimately what I'm going for is interop with JavaFX. When defining a JavaFX property, you usually follow the following standard (with some additional code to make it lazy):

private ObjectProperty<Color> color = new SimpleObjectProperty<>(this, "color", DEFAULT_COLOR);

public ObjectProperty<Color> colorProperty() {
    return color;
}

public Color getColor() {
    return colorProperty.get();
}

public void setColor(Color color) {
    colorProperty().set(color);
}

So what I'm going for is something like this (though the @field obviously doesn't work):

@field:JvmName("color")
@get:JvmName("colorProperty")
val colorProperty: ObjectProperty<Color> =
    SimpleObjectProperty(this, "color", DEFAULT_COLOR)

var color
    get() = colorProperty.get()
    set(value) = colorProperty.set(value)

This would allow the binding capabilities of FXML (which use reflection), follow the standard conventions in Java, and still be nice and easy to use from Kotlin.

In this case I can't use a backing property because I need the color field to be a ObjectProperty<Color>, but the getter and setter for color should be a Color.

Luckily, the reflection from JavaFX is smart enough to still work with just the @get:JvmName("colorProperty"), but there are similar situations with overlapping field names that could use this renaming.

1

There are 1 answers

0
Pinkie Swirl On

No it is not possible. The reason is, that there are cases where there is no backing field (and thus this property abstraction).

From the kotlin examples (creates no backing field):

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

Hence the need for the backing properties workaround.