7

I'm migrating part of application from Java to Kotlin and have a question about that.

What is preferable or better way ?

  1. File with annonation @file:JvmName and funtion inside
@file:JvmName("ClassX")

fun funX() {}

or

  1. Typical class with @JvmStatic annotation inside companion object
class ClassX {
    companion object {
        @JvmStatic
        fun funX() {}
    }
}
madhead
  • 31,729
  • 16
  • 153
  • 201
Esperanz0
  • 1,524
  • 13
  • 35

1 Answers1

10

Let's look at the decompiled code to answer this question.

Kotlin file with a @JvmName annotation like yours:

@file:JvmName("ClassX")

fun funX() {}

will be compiled into a bytecode, analogous to this Java code:

@JvmName(
   name = "ClassX"
)
public final class ClassX {
   public static final void funX() {
   }
}

Pretty similar to what you'd probably write when using Java, right?

A Kotlin class with a companion object like this:

class ClassX {
    companion object {
        @JvmStatic
        fun funX() {}
    }
}

is analogous to this Java code:

public final class ClassX {
   public static final ClassX.Companion Companion = new ClassX.Companion((DefaultConstructorMarker)null);

   @JvmStatic
   public static final void funX() {
      Companion.funX();
   }

   public static final class Companion {
      @JvmStatic
      public final void funX() {
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

As you see, class with a companion object will generate more code.

Is it good or bad? You decide. I'd say it's bad and it's better to use a file with @JvmName annotation. There is also a discussion on Kotlin's forum about this topic: read the best practices.

BTW, you can look at the bytecode and decompiled Java code in IntelliJ IDEA via "Tools" -> "Kotlin" -> "Show Kotlin Bytecode".

madhead
  • 31,729
  • 16
  • 153
  • 201
  • 1
    In addition, they'll be referred to the same way from Java, but not from Kotlin and recommended practice in Kotlin is to use top-level functions: https://stackoverflow.com/questions/54862918/kotlin-top-levels-functions-vs-object-function – Alexey Romanov Aug 05 '19 at 12:24
  • Thanks, @AlexeyRomanov, I've linked Dmitry's statement from the forum here. – madhead Aug 05 '19 at 13:13