I had one constants file in Java, where all my "pu...
# android
c
I had one constants file in Java, where all my "public static final String" were declared. Now I converted that to Kotlin using the AS 3.0 tool. The generated file converted public class -> object -- Why not class? public static final String -> val -- It is understandable. But the places I was using those constants changed to: Constants.TEST -> Constants.INSTANCE.getTEST() -- Any better way to achieve this? All my switch case fails as they need String literals not String object. I know when in Kotlin, but those classes are Java and can't convert whole project in Kotlin at one shot. As I am new to Kotlin.
l
chansek: Use
@JvmStatic
on your string constants, java swicth doesn't need literals, but compile time constants.
const
prefix should also work, and is cleaner
👍 1
d
chansek:
object
at top-level is sorta the same as a static class.
m
there is no such thing as static class in java, unless we're talking nested
c
Can't we access those constants as Constants.TESt instead of Constants.INSTANCE.getTEST()
d
Fair enough, but you know what I mean. public classes with only static variables and methods.
c
Isn't it creates an object Constants class and then accessing the constants through getters?
Correct me if I am wrong
m
well in this case
object
itself is nothing alike, it's just a class with enforced single instance
v
@chansek Yes, you may wrap those variables in companion object where everything inside is static
So you would have something like this
Copy code
companion object {
        val apiKey = "abc"
}
m
you don't even need a class for that in Kotlin, you'll be perfectly fine with top-level declarations
c
What is top level declarations?
m
unlike Java, you can put declarations outside classes
things like
const val CONSTANT = "constant"
no need to put this inside `class`/`object`
v
oh like that also can?
d
@chansek I'm pretty sure this is what you're looking for: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-methods
👍 1
v
But top level declaration can reference from other classes outside the file?
d
Copy code
object Obj {
    @JvmStatic fun foo() {}
    fun bar() {}
}
java:
Obj.foo(); // works fine
Obj.bar(); // error
m
@vincentloi other classes, other files inside the package
c
@David W, not exactly static methods, but just above that doc has Static Fields. Thats what I was looking for. Thanks for the link
d
Ah, right, I skipped over that somehow. @louiscad mentioned this right at the beginning of the thread as well.
l
@chansek For constants, you don't need any
JvmStatic
. The
const
prefix is just made exactly for this, and is available at the top level accessibe in java
NameOfYourKotlineFileKt.YOUR_CONSTANT
, or in an
object
accessing it like in Kotlin
d
ie
Copy code
object Constants {
  const val USERNAME_KEY = "key123423423"
}
m
no, ie.
const val USERNAME_KEY = "key123423423"
without
object Constants
just place it in
constants.kt
file (or any other name)
and you can access the
USERNAME_KEY
directly
the
object
above will work also, but is just not necessary in Kotlin, why make it more complex? 🙂
d
From OP
But the places I was using those constants changed to: Constants.TEST -> Constants.INSTANCE.getTEST() -- Any better way to achieve this?
I'm just trying to get it the same syntax as their entire app is already using.
And also because scoping and grouping stuff is nice. You could add all of your code files to
com.something.else
but instead we group together related stuff in packages.
m
it is exactly grouped together in a package
you just don't need an enclosing class/object in kotlin just to serve as something like 'namespace' declarator
regarding the OP's question - I think it makes more sense to leave the constants file as it is in Java and take care of converting other files first if doing it incrementally
c
@maciekjanusz is that the right way to migrate incrementally? I thought different way.
I am planning to change POJOs 1st, then some constant classes, then utils classes and then move into Activities and Fragments
m
the problem with object constants is that it polutes the auto complete
i mean, top level declaration **
i prefer giving it a namespace with singleton object
its just preference
v
Agree, you’ll just end up with lots of imports at the top whereas with one object, just one line. Also you won’t get mixed up with a variable and const if placed in an object
m
or (a better solution, but wastefull i think) is to use a normal class, and get it via dagger provider (util module or sth)
but that is not so convenient, you have to inject it just to use a constant class
so imo, object better
m
I agree it's a matter of preference, depends heavily of the project and context
@chansek looks like you can't do it in this order specifically because of this naming issue, but that shouldn't worry you. constants are just constants, it matters least which language you use there, you should be more worried about migrating java logic to kotlin first 🙂
c
I do it in this way, because being a novice I don't need to learn the language features to start migration.
THis way makes me learn gradually as migration becomes more and more.
m
I understand your intent, but it looks like you can't do it the way you planned without altering Java code for kotlin interop.