Background
I'm trying to convert this Ebean example from Java into Kotlin: http://ebean-orm.github.io/docs/mapping/extension/dbenumvalue
Here's the sample Java code:
public enum Status {
NEW("N"),
ACTIVE("A"),
INACTIVE("I");
String dbValue;
Status(String dbValue) {
this.dbValue = dbValue;
}
// annotate a method that returns the value
// in the DB that the enum element maps to
@DbEnumValue
public String getValue() {
return dbValue;
}
}
Kotlin
I expected the following in Kotlin:
// ERROR: This annotation is not available to target 'value parameter'
enum class Status(@DbEnumValue(storage = DbEnumType.VARCHAR) value: String) {
NEW("N"),
ACTIVE("A"),
INACTIVE("I")
}
Or maybe:
// ERROR: Expecting , or ) after "value:String"
enum class Status(val value:String
@DbEnumValue(storage = DbEnumType.VARCHAR)
get() = value) {
NEW("N"),
ACTIVE("A"),
INACTIVE("I")
}
The following makes sense to me and actually compiles, but the combination of the dbValue
parameter for the constructor with a separate value
field with getter for the annotation feels wasteful somehow.
enum class Status (val dbValue:String) {
NEW("N"),
ACTIVE("A"),
INACTIVE("I");
val value: String
@DbEnumValue(storage = DbEnumType.VARCHAR)
get() = dbValue
}
When I let IntelliJ convert the Java to Kotlin, it does this:
enum class Status private constructor(dbValue: String) {
NEW("N"),
ACTIVE("A"),
INACTIVE("I");
var value: String internal set
init {
@DbEnumValue(storage = DbEnumType.VARCHAR)
this.value = dbValue
}
}
I added the annotation to what IntelliJ produced, but it took me several guesses to figure out where to put it.
Questions
- Why
private constructor
? - Why
var value
without a get()? - What is
internal set
? - Why
init
? - Why the extra
dbValue
variable? (I think to pass the value from the constructor to the public annotated get method). - Is that even right?
- What is the idiomatic way to do this?
Any explanation, correction, or improvement would be appreciated. If you think this belongs on codeReview, I'm OK with you moving it.