[Java/Kotlin] Kotlin은 static이 없다.

Jay·2021년 3월 18일
0

Java&Kotlin

목록 보기
28/30
post-thumbnail

Kotlin에는 static 키워드가 없다.
🧐 그럼 코틀린에선 static을 대체하기 위해 무엇을 써야 할까?
우선, 안드로이드에선 정적(static) 변수/메서드를 사용하는 경우가 보통은 아래와 같다.

  • Activity, Fragment의 인텐트 extra로 사용하는 키
  • Log 출력을 위한 Tag 이름 정의
  • View 내부에서 사용하는 고정된 길이 값 (너비, 높이 등)
  • 각종 유틸리티 클래스 내 메서드 (빠른 계산을 요구하는...등)
    🖐 패키지 내에 함수를 선언해서 사용할 수 있다!

코틀린에서 static을 대체하기 위한 옵션은 아래와 같다.

  • Top-level functions
  • Top-level constants
  • Companion object functions
  • Object instance

코틀린의 1급 객체는 함수니까..😁

그럼 하나씩 알아보자.


Top-level functions/properties

Functions main()

자바에선 main 함수 작성시 많은 보일러 플레이트 코드가 있다.
클래스 안에 public static void main(String[] args)와 같이 작성해야 한다.
코틀린에선 이를 Top-level function으로 구현해주면 된다.

Get rid of utility classes

많은 Util, Helper 클래스를 작성해본적이 있다 분명.
Util 클래스 안에 static 키워드로 범용적인 메소드를 구현하였다.
Kotlin에서는 이를 Top-level function으로 작성해주면 된다.
그리고 해당 패키지 내부에서 사용하거나 다른 패키지에서 해당 Top-level function을 import해서 사용 가능하다.

[JAVA]
public class StringUtils {
  private StringUtils() { /* Forbid instantiation of utility class */ }   

  public static int lowerCaseCount(String value) {
      return value.chars().reduce(0, 
              (count, current) -> count + (Character.isLowerCase(current) ? 1 : 0));
  }
}
[Kotlin]
package toplevel

fun lowerCaseCount(value: String): Int = value.count { it.isLowerCase() }

Top-level Constants

property 또한 top-level에 작성 가능하다.
물론, immutable하게 선언해야 한다.

[JAVA]
class Foo{
     public static final String BAR = "bar";
}
[Kotlin]
const val BAR = "bar"

Private top-level functions

Get rid of utility classes에서 만든 lowerCaseCount 메소드가 한 클래스에서만 필요하다면 Java의 경우 아래와 같다.

public class MyClass {
  private String myString;
  public void doSomething() {
    int count = lowerCaseCount(myString);
    ...
  }
  private static int lowerCaseCount(String value) { ... } // private static pure function
}

코틀린에서는 해당 static 메소드를 클래스 밖으로 빼서 해당 파일 내에 private top-level function으로 구현하여 해당 파일 내에서만 구현 가능하게 할 수 있다.


Object singletons

코틀린에서는 싱글톤 패턴을 Object 키워드로 제공한다.
그래서, 자바에서 싱글톤 패턴 구현 시 static 키워들 썼다면 Object 키워드로 대체할 수 있다!


Companion Object ::: 자바와 비슷하게 사용하기

static 메소드에서 Non-static method에 접근해야 하는 경우엔 어떻게 해야할까?
이럴 땐 Companion object를 사용하면 된다.
(static에 대한 대체로 무조건적으로 Companion Object을 사용하는 사람들이 있는데 매우 잘못된...어 난데)


Static factory methods

Companion objects는 클래스 내부에 정의된 Singleton value이다.
Companion object 내 멤버들은 클래스 이름으로 호출할 수 있다.
게다가 Companion object는 클래스 인스턴스의 private 멤버들에 접근 할 수 있기 때문에 팩토리 메소드에 특히 유용하다!

class Rocket private constructor() {
  private fun attachPropellers() { ... }

  companion object {
    fun build(): Rocket {
      val rocket = Rocket()  // can call private constructor
      rocket.attachPropellers() // can call private function
      return rocket
    }
  }
}

fun main() {
  val rocket = Rocket.build() // Companion function called using the accompanied class name
}

Util 함수를 만들기

우선, 안 좋은 예제 부터 보자.
(보통 이렇게 쓰는 사람들이 많다..어 나도)

❌ 아래와 같은 코드는 지양!

object SampleUtils{
	fun jsonString(map : mutableMap) : String{
    	return objectMapper.writeValueAsString(map)
    }
}

//사용할 땐 아래처럼..
val map : MutableMap<String, Any?> = mutableMapOf("K" to "V")
SampleUtils.jsonString(map) // {"K":"V"}

⭕️ 이렇게 쓰자!

fun mutableMap.jsonString() : String = objectMapper.writeValueAsString(this)

//사용은 아래 처럼
val map : MutableMap<String, Any?> = mutableMapOf("K" to "V")
map.jsonString()

Reference

profile
developer

0개의 댓글