30

Please tell me, is there any difference (in terms of Java) in this examples:

  1. object DefaultValues {
        val FILES_TO_DOWNLOAD = 100
    }
    

    and

    class DefaultValues {
        companion object {
            val FILES_TO_DOWNLOAD = 100
        }
    }
    
  2. Without class or object wrapper:

    const val DEFAULT_FILES_TO_DOWNLOAD = 100
    

    and

    val DEFAULT_FILES_TO_DOWNLOAD = 100
    

What is the true way to define?:

public static final int FILES_TO_DOWNLOAD = 100
hotkey
  • 140,743
  • 39
  • 371
  • 326
Letfar
  • 3,253
  • 6
  • 25
  • 35

1 Answers1

29

You can use Kotlin bytecode viewer to find out what these options are compiled to.

With Kotlin 1.0.2 the compiled bytecode shows that

  1. val property in object or companion object is compiled into a private static final field inside the class:

     // access flags 0x1A
     private final static I FILES_TO_DOWNLOAD = 100
    

    and a getter, which is called when referring to the property:

     // access flags 0x1019
     public final static synthetic access$getFILES_TO_DOWNLOAD$cp()I
    

    From Java, the getter can be called as DefaultValues.INSTANCE.getFILES_TO_DOWNLOAD() or DefaultValues.Companion.getFILES_TO_DOWNLOAD() respectively.

  2. Non-const top level property is compiled to the same to (1) with only difference that the field and getter are placed inside FilenameKt class now.

    But top level const val is compiled into a public static final field:

    // access flags 0x19
    public final static I DEFAULT_FILES_TO_DOWNLOAD = 100
    

    The same public static final field will be produced when a const val is declared inside an object. Also, you can achieve the same resulting bytecode if you add @JvmField annotation to the properties declared in (1).


Concluding that, you can define public static final field using const or @JvmField either in an object or at top level.

Community
  • 1
  • 1
hotkey
  • 140,743
  • 39
  • 371
  • 326
  • how about internal var x;? is it make var static? – UmAnusorn Dec 13 '16 at 09:57
  • @umitems, `internal` is only a visibility modifier, should not make much difference in the bytecode with a normal public `var`. – hotkey Dec 13 '16 at 10:57
  • Thank you for your answer, I see. I just tried to convert public static int x in java file to Kotlin file then I got internal var x instead. – UmAnusorn Dec 13 '16 at 11:04
  • Does it implies any difference in terms of performance and bytecode size? – Louis CAD Feb 07 '17 at 20:10
  • 2
    @LouisCAD, `const val` and `@JvmField` are more efficient than simple `val`, but this is mostly because of the getter calls, while JVM is quite good at inlining functions and especially getters at runtime. I guess in a long run the performance difference should be negligible (for a non-critical part of the code). As to the bytecode size, the second option produces smaller bytecode as well, but your are unlikely to save much optimizing this anyway. – hotkey Feb 07 '17 at 20:42