4

Perhaps it was bad practice but in Java I would often create something like:

public class MyService extends Service {

  public static final String ACTION_CONNECTED = "blablabla";

...
}

And reference it in another class like:

MyService.ACTION_CONNECTED

This was great. I could keep my constants nicely associated with their class.

I can't seem to find an equivalent in Kotlin. I see solutions flying around suggesting people create constants files (objects) but I don't think that's very elegant. I want there to be some way to expose a top-level const val BLAB outside its file so I can keep my ClassName.CONSTANT syntax going but it doesn't look like it's in the cards.

Is there (and what is it) a Kotlin equilivant to the good old public static final with regard to sharing constants between classes?

kkemper
  • 307
  • 2
  • 15
  • 1
    Does this answer your question? [What is the equivalent of Java static final fields in Kotlin?](https://stackoverflow.com/questions/40352879/what-is-the-equivalent-of-java-static-final-fields-in-kotlin) – jsamol Apr 16 '20 at 09:11
  • I guess what I was looking for is how in Java the constant is scoped to the class (not global) but public. I think that makes the code more readable and it's nice to be able to reuse constant names without ambiguity. That said it actually looks like the companion object does what I want! No one seems to make that example use-case obvious (at lest to me). – kkemper Apr 17 '20 at 02:07

3 Answers3

3
class MyService  {
    companion object {
        @JvmStatic const val ACTION_CONNECTED = "blablabla"
    }
}

MyService.ACTION_CONNECTED 

This will be the equivalent of public static final for kotlin

Destroyer
  • 785
  • 8
  • 20
  • 1
    If your static variables or methods are referenced from only Java, you could also add a @JvmStatic annotation for the Java-like `MyService.ACTION_CONNECTED` static syntax – Haroon Apr 16 '20 at 01:56
  • I wouldn't say "from _only_ Java"; it's useful if they are referenced from both Java and Kotlin, too. – Alexey Romanov Apr 16 '20 at 10:42
  • I've been using companion objects but this scoping was never obvious to me in the documentation. For some reason I had it in my head that you can only access things in the companion object within the associated class. That extra ```MyService.ACTION_CONNECTED``` made the difference. Thanks! – kkemper Apr 17 '20 at 02:11
2

If you want to create a final variable in kotlin, use val instead of using var

val LastCount = 1

and for creating a static variable use companion object key

companion object{
    val lastCount = 1
   }

now you want to have access to this variable in other classes. so create a new class like this:

class Counter{
   companion object{
    val lastCount = 1
   }
}

and then use it all over the project like this

Counter.lastCount 
1

According to Jetbrains in this video: https://www.coursera.org/learn/kotlin-for-java-developers/lecture/85GKr/objects-object-expressions-companion-objects

There are 3 ways to create static methods or functions for a class:

  1. Declare static members at the top level (Default approach)
  2. Declare them inside objects (Singletons)
  3. Declare them inside companion objects

Using method 1 should be the easiest approach for you if you want to mimic the experience in Java as close as possible. You will be able to access the members using either the getter under the hood or using direct access. Here's an example:

MyService.kt will be the name of your Kotlin file.

val ACTION_CONNECTED = "blablabla"

class MyService :Service{
//your other class details
}

You can access it like this from another Kotlin file or Activity:

val myAction=ACTION_CONNECTED

It would also be better if you mark it as const, since it is a constant value like this:

 const val ACTION_CONNECTED = "blablabla"
Mena
  • 3,019
  • 1
  • 25
  • 54