Intro

코틀린에서는 Class의 내부가 아닌, 소스 파일의 최상위 수준(모든 다른 클래스의 밖)에 함수와 프로퍼티를 선언할 수 있다.

(자바의 경우 모든 함수와 프로퍼티는 무조건 클래스 내부에 선언되어야 한다.)

정의/특징

1. 최상위 함수

소스 파일(클래스 내부X)에 함수를 선언하면 최상위 함수가 된다. 심지어 자바 파일에서 해당 함수를 호출하는 것 역시 가능하다. 어떻게 이것이 가능한 걸까?

코틀린 코드를 자바 코드로 디컴파일해서 확인해보면 이유를 알 수 있다.

// testFunction.kt

package testPackage

fun testFunction() = println("test")

// Decompile to Java

public final class TestFunctionKt {
   public static final void testFunction() {
      String var0 = "test";
      System.out.println(var0);
   }
}

코틀린 파일 이름을 클래스명으로한 클래스가 생성되는 것을 확인할 수 있다. 코틀린은 개발자의 편의를 위해 스스로 클래스를 선언하고 정적 메서드를 생성했던 것이다.

따라서 코틀린으로 최상위 함수로 선언한 함수를 자바 코드에서 해당 파일 명의 클래스로 호출할 수 있다.

import testPackage.TestFunctionKt;

		...
		TestFunctionKt.testFunction();

파일에 대응하는 클래스의 이름 변경하기

파일에 @JvmName 어노테이션을 추가하여 자동으로 생성되는 클래스 명을 지정할 수 있다.

⇒ 어노테이션은 파일의 맨 앞, 패키지 이름 선언 이전에 위치해야 함

@file:JvmName(Tf)
package testPackage

fun testFunction() = println("test")

// Java에서 호출

import testPackage.Tf;

		...
		Tf.testFunction();

2. 최상위 프로퍼티

함수와 만찬가지로 프로퍼티도 파일의 최상위 수준에 놓을 수 있다.

// testFunction.kt

const val first = "first"
val second = "second"
var third = "third"

// Decompile to Java

public final class TestFunctionKt {
   @NotNull
   public static final String first = "first";
   @NotNull
   private static final String second = "second";
   @NotNull
   private static String third = "third";

   @NotNull
   public static final String getSecond() {
      return second;
   }

   @NotNull
   public static final String getThird() {
      return third;
   }

   public static final void setThird(@NotNull String var0) {
      Intrinsics.checkNotNullParameter(var0, "<set-?>");
      third = var0;
   }
}

최상위 함수와 동일하게 프로퍼티가 선언된 파일 명으로 클래스가 선언되고 내부의 정적 필드로 선언 되었다.