Usually, we can write the following code in kotlin:
val hasValue : Boolean
@JvmName("hasValue") get() = true
This will generate the method hasValue()
instead of getHasValue()
for Java interop.
However, in an interface, this gives me a compile error:
val hasValue : Boolean
@JvmName("hasValue") get
The same goes for the following declaration in an abstract class:
abstract val hasValue : Boolean
@JvmName("hasValue") get
So here is my question: How can I tell the kotlin compiler to use hasValue()
instead of getHasValue()
for getters (and setters) of properties in a kotlin interfaces?
All methods of interface are abstract and public in nature. The class which implements interface need to provide functionality for the methods declare in the interface. One can use interface to implement PM (Partial multiple inheritance) and DMD (Dynamic memory dispatch). Interface always implements in derived class.
As you can see, only setNumber is part of MyInterface. Consumers do not need to know about how the number is stored, therefore it is an implementation detail. Besides, in Java you name classes and interfaces in PascalCase rather than camelCase.
Interface contains only abstract methods that can’t be instantiated and it is declared by keyword interface. A class that is declared with the abstract keyword is known as an abstract class in Java.
How JVM Works – JVM Architecture? In C++, if a class has at least one pure virtual function, then the class becomes abstract. Unlike C++, in Java, a separate keyword abstract is used to make a class abstract. Following are some important observations about abstract classes in Java. An instance of an abstract class can not be created.
There is a workaround, see: https://youtrack.jetbrains.com/issue/KT-31420
Simply suppress this INAPPLICABLE_JVM_NAME
error with annotation: @Suppress("INAPPLICABLE_JVM_NAME")
I think Kotlin has some restriction on using @JvmName
on open
/override
property/function. Prohibiting the use of @JvmName
on open
/override
function can avoid having different jvmName on the interface/superclass and subclass.
In the following example, I am trying to annotate the overrided property getter with a jvmName (hasValueImpl
) which is different from the interface (hasValue
) and it gives compilation error:
'@JvmName' annotation is not applicable to this declaration
interface Abstract { @get:JvmName("hasValue") //Compile error val hasValue: Boolean get() = false } open class Impl : Abstract { @get:JvmName("hasValueImpl") //Compile error final override val hasValue: Boolean get() = false @get:JvmName("hasValue2") //Compile error if hasValue2 is open val hasValue2: Boolean get() = false }
I turns out, this is possible:
interface Foo {
val bar: String
@get:JvmName("getAwesomeBar") get
}
However, it is interesting that this does NOT work:
interface Foo {
@get:JvmName("getAwesomeBar")
val bar: String
}
But, this does work:
class Foo {
val bar: String
@JvmName("getAwesomeBar") get() = "My bar value"
}
and this works too!
class Foo {
@get:JvmName("getAwesomeBar")
val bar: String
get() = "My bar value"
}
Why you need to have the extra get:
when doing this in interfaces is beyond me. I'm sure there is a reason for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With