I am new to Kotlin. I have a kotlin Object class like
#Parcelize
object AddCard
I want to access it in a Java class. if I have to do so I read that i have to give #JVMStatic annotation to the object class.something like
#JVMStatic
#Parcelize
object AddCard
when I add the annotation it says
This annotation is not applicable to target object.
How to handle this?
You don't have to do anything special. You can access it from Java with just AddCard.INSTANCE.
Related
How is #Named used with #BindsInstance? I have the this component
interface AppComponent : AndroidInjector<MyApplication>{
#Component.Builder
abstract class Builder : AndroidInjector.Builder<MyApplication>() {
#BindsInstance
abstract fun preferenceName( #Named("PreferenceName") name : String ) : Builder
}
}
and trying to inject in MyApplication
#Inject
#Named("PreferenceName")
lateinit var prefName : String
But it fails with MissingBinding for String. I could resolve this with a module provider but trying to avoid provider for constants.
Update: Dagger 2.25.2 has eliminated the need for workaround:
Kotlin support
ii. Qualifier annotations on fields can now be understood without
The need for #field:MyQualifier (646e033)
iii. #Module object classes no longer need #JvmStatic on the
provides methods. (0da2180)
This doesn't have anything to do with #BindsInstance, but rather the #Named annotations on fields. You can tell from the "MissingBinding for String", which would otherwise give you an error about a Named string.
As in Svetlozar Kostadinov's article Correct usage of Dagger 2 #Named annotation in Kotlin, you'll need to clarify to Kotlin that you'd like the annotations to apply to the field.
#field:[Inject Named("PreferenceName")]
lateinit var prefName : String;
As Svetlozar puts it:
The reason is because in Kotlin annotations need to be slightly more complicated in order to work as expected from Java perspective. That’s coming from the fact that one Kotlin element may be a facade of multiple Java elements emitted in the bytecode. For example a Kotlin property is a facade of an underlying Java member variable, a getter and a setter. You annotate the property but what Dagger expects to be annotated is the underlying field.
Related: Dagger 2 constructor injection in kotlin with Named arguments
I am reading the Kotlin in Action book and trying to understand Companion Objects better, are there any other uses for Companion Ojbects other than adding method implementations from an interface/abstract class?
I came across a way of instantiating an object which only works if the class is abstract:
fun main(args: Array<String>) {
Fruit.showColor()
}
class Fruit(val name: String) {
companion object : Apple()
}
abstract class Apple {
fun showColor(){
print("I am an apple")
};
}
My mental model for companion object is language level support for safe singletons. i.e. instead of static methods on a class for Factory or Util methods, you can provide those related methods on the Singleton companion object.
The Companion status gives you a lot of default scoping wins that are similar to the java class with static methods.
Your example seems invalid, because why is the Fruit "singleton" an Apple?
Is it possible to create an extension function and call it as if it were static?
For Example...
fun System.sayByeAndExit() {
println("Goodbye!")
System.exit()
}
fun main(args: Array<String>) {
System.sayByeAndExit() // I'd like to be able to call this
}
I know that the code sample doesn't work...
I understand that kotlin's extension functions are resolved statically, as mentioned in the Kotlin Reference (Extension Functions), but this does not mean they can be called as if they were static functions within a class (in a Java sense).
I also understand that this code will not work because there is no instance of System to pass into the method that the compiler will generate; therefore it won't compile.
Why would I want this?
Some of you might be wondering why this behaviour is desirable. I can understand why you would think that is isn't, so here are some reasons:
It has all of the benefits that standard extension functions give.
An instance of the class doesn't need to be created just to access the extra functionality.
The functions can be accessed from an application-wide context (provided the class is visible).
To summarise...
Does Kotlin have a way to "hook" a static function onto a class? I'd love to know.
You are really asking for "extension functions for a Class reference" or "adding static methods to existing classes" which was covered by another question here: How can one add static methods to Java classes in Kotlin which is covered by a feature request KT-11968
Extension functions cannot be added to anything that does not have an instance. A reference to a Class is not an instance and therefore you cannot extend something like java.lang.System. You can however extend a companion object of an existing class. For example:
class LibraryThing {
companion object { /* ... */ }
}
Allows you to extend LibraryThing.Companion and therefore calling some new myExtension() method would look like you are extending the Class reference itself, when really you are extending the singleton instance of the companion object:
fun LibraryThing.Companion.myExtension() = "foo"
LibraryThing.Companion.myExtension() // results in "foo"
LibraryThing.myExtension() // results in "foo"
Therefore you might find some Kotlin libraries add empty companion objects just for this case. Others do not, and for those you are "out of luck." Since Java does not have companion objects, you cannot do the same for Java either.
The other commonly requested feature is to take an existing Java static method that accepts an instance of a class as the first parameter, and make it behave as an extension function. This is tracked by issues KT-5261, KT-2844, KT-732, KT-3487 and probably other feature requests.
You can define extension function for an object and use it from system-wide context. An object will be created only once.
object MyClz
fun MyClz.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
Or
class MyClz {
companion object
}
fun MyClz.Companion.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
i want to add some extension function to an already defined class‘s companion object, like
fun Toast.Companion.showImageToast(str : String) {
}
and also i like to do the same thing on interfaces, e.g
fun Runnable.Companion.mainHandler() {
}
I've consulted the documentation, only to find syntax for define extension function for companion object in a user defined class, not for class that don't have a companion object
can i have any chance to do this in kotlin ?
In Kotlin 1.0, if a class does not define a companion object, it is not possible to define extension functions for that companion object. It's also not possible to define extension functions for Java classes and interfaces such as Runnable.
Is it possible to add a new static method to the java.lang.Math class in Kotlin? Usually, such things are possible in Kotlin thanks to Kotlin Extensions.
I already tried doing the following in a file I made called Extensions.kt:
fun Math.Companion.clamp(value:Double,minValue:Double,maxValue:Double):Double
{
return Math.max(Math.min(value,maxValue),minValue)
}
but Math.Companion could not be resolved...
As of Kotlin 1.3, this is not possible. However, it's being considered for a future release!
To help this feature get implemented, go vote on this issue: https://youtrack.jetbrains.com/issue/KT-11968
Because all proposals are basically in limbo right now, I wouldn't hold my breath that this will get in any time soon
I think this is not possible. Documentation says the following:
If a class has a companion object defined, you can also define extension functions and properties for the companion object.
The Math class is a Java class, not a Kotlin one and does not have a companion object in it. You can add a clamp method to the Double class instead.
As of Kotlin 1.2 it is still not possible.
As a workaround, to statically "extend" Environment class I am currently using:
Class EnvironmentExtensions {
companion object {
#JvmStatic
fun getSomething(): File {
...
return Environment.something()
}
}
}
It is not an ideal solution but IntelliJ/Android Studio code completion helps with the usage:
val something = EnvironmentExtensions.getSomething()