For example I have Java class (from external library):
class A {} // This is Java class
I want to add extension functions written on Kotlin and call it as:
A.foo() // This is call of extension function `foo` from Kotlin code
As I understand, right now it is impossible to do in Kotlin because it support "static" extension functions for KClass-es with companion object only. Right?
Seems like nothing to prevent to implement such functionality in Kotlin later. Right?
UPDATE 2019-06-12: This question doesn't answer to my question because my question about compatibility of Kotlin extension functions with Java classes.
You're right. In Kotlin 1.0, you can define extension functions on a companion object of a Kotlin class, and such functions can be called using the A.foo() syntax. Support for defining static extension functions on Java classes is a possible feature for future versions of Kotlin, but it's not on the roadmap of Kotlin 1.1 at this time.
Related
I declared an inline class
#JvmInline
value class Creator<T>(val type: KClass<T>);
, and declared an interface
interface Itf {
fun <T> creator(type: KClass<T>): Creator<T>;
}
I want to implement this interface by generating the bytecode by asm(https://asm.ow2.io/ 1).
I found java method decompiled from bytecode is
public KClass<T> creator-9k1ZQyY();
The java method name is “creator-9k1ZQyY”. the suffix “-9k1ZQyY” is added by kotlin compiler and I know why kotlin compiler did it.
This suffix is very important for bytecode generator.
My question:
If the interface and inline class are stable, can kotlin compiler guarantee that suffix is stable too? Does that suffix have nothing to do with the version of kotlin-compiler?
The docs seem to suggest the mangling is stable:
functions using inline classes are mangled by adding some stable hashcode to the function name
As noted in the same doc, the mangling scheme has changed once with the version 1.4.30 of the Kotlin compiler, but I would consider it quite stable nonetheless. They even provided a flag to use the old scheme to generate binary compatible code, so I'm assuming it's not only unlikely to change again, but even if it does, it will surely be done with some way to keep compatibility.
I am very new to Kotlin development and I came across custom annotation classes in the documentation.
Is there a way for me to use an annotation on a function as a way to pre-populate some variables, or to run a decorator function before running the annotated function?
Something like:
class TestClass {
#Friendly("Hello World")
private fun testFun() {
greet()
//does something else
}
}
with an annotation class like
#Target(AnnotationTarget.FUNCTION)
#Retention(AnnotationRetention.BINARY)
annotation class Friendly(val message: String) {
fun greet() {
println(message)
}
}
I know this isn't valid Kotlin code, but I can't find any examples on how to actually use values from annotations without using reflection (if it's even possible)
Please let me know if I can do something like this, and more usefully, a better resource on annotation classes for Kotlin?
To make use of your custom annotations, you need to either create your own annotation processor (and use kapt Kotlin compiler plugin) to generate some new sources (but not modify existing!) at compile time, or use #Retention(AnnotationRetention.RUNTIME) meta-annotation (which is default in Kotlin), so that they could be accessed via reflection in runtime.
#Retention(AnnotationRetention.BINARY) meta-annotation you're using is equivalent of #Retention(RetentionPolicy.CLASS) in java, which is mostly useless (see https://stackoverflow.com/a/5971247/13968673).
What you're trying to do with annotations (call some additional code before/after method execution) reminds me aspect-oriented programming. Take a look at Spring AOP and AspectJ frameworks, following this paradigm, and their approach for annotations processing. TL;DR: Spring AOP is processing annotations in runtime, generating proxy-classes with respectful code, while AspectJ is using its own compiler (even not an annotation processor, cause it also introduces its own syntactic extension for java language), and can generate respectful bytecode at compile-time. They both are originally java-oriented, but with some configurational pain could be used with Kotlin too.
Data classes print out just fine in MPP projects. When I toString() the KClass object for my class, I get:
class com.example.MySimpleClass (Kotlin reflection is not available)
How Can I do what data class does and have a nice clean name without reflection?
I don't have it set up myself to test, so answer is based purely on documentation:
KClass.simpleName is available in Common code; qualifiedName isn't, but since 1.3 it is on every platform, so you could define an expect fun in your multiplatform part and make all actual implementations access qualifiedName.
Is it a good idea to cut my code anywhere around the project in other classes using extension functions?
I mean what is the point?For what exactly a class fun can leak to other classes?
Friends, I'm new to Kotlin and I appreciate if anyone can provide a real example of using extension fun in kotlin.
class Car{
//any code you imagine
}
class Garage{
//any code
fun Car.boost(){
//boost implementation
}
}
As stated in Kotlin Coding Conventions, extension functions are a good practice:
Use extension functions liberally. Every time you have a function that
works primarily on an object, consider making it an extension function
accepting that object as a receiver.
There are a few reasons for that:
Extension functions keep your class small and easy to reason about
Extension functions force you to have good API, since they cannot access any private members of your class
Extension functions have zero cost on performance, since they're simply rewritten by Kotlin compiler into static methods, with method receiver (the class you're extending) as its first argument
I`m new at kotlin and want to build a multiplatform application.
For the common part I want to use data classes that contains platform specific functions.
Is it possible to use the kotlin data class in a platform specific declaration?
something like
expect data class Foo(val bar: String)
best regards
From Kotlin's docs on Platform Specific Declarations:
Expected declarations never contain any implementation code.
Since data classes generate implementations they can't be used in expect declarations. The actual implementation can be a data class since it does not change the semantics of the declared class.
expect class Some {}
actual data class Some(val test: UUID)