I'm trying to convert the following code to Kotlin AND still have one of the classes (Foo) used by Java. What is the proper way of making this conversion?
Original Java:
public class Foo {
public static final String C_ID = "ID";
public static final String C_NAME = "NAME";
public static final String[] VALUES = {"X", "Y", "Z"};
public static String[] getAll() {
return new String[] {C_ID, C_NAME};
}
}
public class Bar {
public void doStuff() {
String var1 = Foo.C_ID;
String[] array1 = Foo.VALUES;
String[] array2 = Foo.getAll();
}
}
Auto conversion fo Foo to Kotlin
object Foo {
val C_ID = "ID"
val C_NAME = "NAME"
val VALUES = arrayOf("X", "Y", "Z")
val all: Array<String>
get() = arrayOf(C_ID, C_NAME)
}
Problem:
Bar class can no longer access C_ID or VALUES (error: "private access")
if I put "const" in front of C_ID, it works... but I cannot do the same with VALUES ("const" can ONLY be used on primatives or String)
Is there a different way I should be doing this (so both Java code and Kotlin code can access everything in Foo)?
The current semantics come from Kotlin Beta Candidate:
According to this and to the reference, there are three ways of working with properties of a Kotlin
object
from Java:Use
Foo.INSTANCE
.By default, properties of
object
won't be static fields for Java, but Java can access the properties throughFoo
object instance --Foo.INSTANCE
.So the expression will be
Foo.INSTANCE.getC_ID()
.Mark a property with
@JvmStatic
annotation:This will generate static getter for
C_ID
instead ofFoo
instance getter which will be accessible asFoo.getC_ID()
.Use
@JvmField
annotation on property declaration:This will make Kotlin compiler generate a static field for Java instead of property. Then in Java you can access it as a static field:
Foo.C_ID
.But it won't work on properties without backing fields like
all
in your example.For primitives, as you stated, one can use
const
which will have the same effect as@JvmField
in terms of visibility in Java.By the way, when it comes to methods, the situation is the same, and there is
@JvmStatic
annotation for them.it's better if you create new kotlin file just for constants.
create Constants.kt file and paste below code.
in your main activity you can access the constants by the constant name the android studio will automatically import the constants. here is my mainActivity:
I was able to get log output successfully
In your foo class you can put those properties and the method inside a companion object:
Then you can call Foo.getAll(), and Foo.C_ID, Foo.C_NAME and Foo.VALUES.
You should be able to access the values "the kotlin way":
With as result: