Programming

java์—์„œ Kotlin ์ฝ”๋“œ ์‚ฌ์šฉํ•˜๊ธฐ

Taylor Kang 2021. 6. 17. 20:05

package level function

org.example.AppKt์ž๋ฐ” ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ๋‚ด๋ถ€ static method ๋กœ ์ปดํŒŒ์ผ ๋จ.

AppKt : ํŒŒ์ผ๋ช…

// app.kt
package org.example

class Util

fun getTime() { /*...*/ }
// Java
new org.example.Util();

org.example.AppKt.getTime();

@file:JvmName("DemoUtils"): ์ƒ์„ฑ๋  Java ํด๋ž˜์Šค ๋ช…์„ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ

@file:JvmName("DemoUtils")

package org.example

class Util

fun getTime() { /*...*/ }
// Java
new org.example.Util();

org.example.DemoUtils.getTime();
  • ๋‹ค์ˆ˜์˜ ํŒŒ์ผ์— ๋™์ผํ•œ @JvmName ์„ ์„ค์ •ํ•˜๋Š” ๊ฒฝ์šฐ โ†’์—๋Ÿฌ ๋ฐœ์ƒ
  • ํ•˜์ง€๋งŒ @file: JvmMultifileClass ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋กœ ์ƒ์„ฑ๋จ
// oldutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass

package org.example

fun getTime() { /*...*/ }
// newutils.kt
@file:JvmName("Utils")
@file:JvmMultifileClass

package org.example

fun getDate() { /*...*/ }
// Java
org.example.Utils.getTime();
org.example.Utils.getDate();

Static methods

@JvmStatic ์ฝ”ํ‹€๋ฆฐ์˜ named object ๋‚˜ companion object์— ์„ ์–ธ๋œ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผ

C.INSTANCE.callStatic()

  • companion object
class C {
    companion object {
        @JvmStatic fun callStatic() {}
        fun callNonStatic() {}
    }
}
C.callStatic(); // works fine
C.callNonStatic(); // error: not a static method
C.Companion.callStatic(); // instance method remains
C.Companion.callNonStatic(); // the only way it works
  • named object
object Obj {
    @JvmStatic fun callStatic() {}
    fun callNonStatic() {}
}
Obj.callStatic(); // works fine
Obj.callNonStatic(); // error
Obj.INSTANCE.callNonStatic(); // works, a call through the singleton instance
Obj.INSTANCE.callStatic(); // works too

*kotlin1.3 ๋ถ€ํ„ฐ interface ๋‚ด์˜ companion object ์—๋„ @JvmStatic ์‚ฌ์šฉ๊ฐ€๋Šฅ
(interface ๋‚ด์˜ static method ์„ ์–ธ์€ java1.8๋ถ€ํ„ฐ ๊ฐ€๋Šฅ)

Instance fields

์ฝ”ํ‹€๋ฆฐ์—์„œ ์†์„ฑ๋“ค์€ ๋ณดํ†ต getter,setter๋ฅผ ํ†ตํ•ด ๋…ธ์ถœ๋˜์ง€๋งŒ, @JvmField๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒŒํ„ฐ ๋ฉ”์„œ๋“œ ์ƒ์„ฑ์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋ฐฑ์—… ํ•„๋“œ์— ์ง์ ‘์ ์œผ๋กœ ์•ก์„ธ์Šค ๊ฐ€๋Šฅํ•˜๋‹ค.

@JvmField : ์ฝ”ํ‹€๋ฆฐ property ๋ฅผ ์ž๋ฐ”์—์„œ ํ•„๋“œ๋กœ ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ

class User(id: String) {
    @JvmField val ID = id
}
// Java
class JavaClient {
    public String getID(User user) {
        return user.ID;
    }
}

Static fields

์ฝ”ํ‹€๋ฆฐ์˜ named object(singleton) ๋‚˜ companion object์— ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผ

  • @JvmField ์‚ฌ์šฉ
class Key(val value: Int) {
    companion object {
        @JvmField
        val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }
    }
}
// Java
Key.COMPARATOR.compare(key1, key2);
// public static final field in Key class
  • lateinit ์œผ๋กœ ์„ ์–ธ
object Singleton {
    lateinit var provider: Provider
}
// Java
Singleton.provider = new Provider();
// public static non-final field in Singleton class
  • const๋กœ ์„ ์–ธ

    In Kotlin, the only types that can be const are primitives, such as int, float, and String. In this case, because BACKUP_PATH is a string, we can get better performance by using const val rather than a val annotated with @JvmField, while retaining the ability to access the value as a field.

    @JvmField์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ val ์–ด๋…ธํ…Œ์ดํŠธ ๋ณด๋‹ค const val ๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋” ์ข‹์€ ํผํฌ๋จผ์Šค๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

// file example.kt

object Obj {
    const val CONST = 1
}

class C {
    companion object {
        const val VERSION = 9
    }
}

const val MAX = 239
int const = Obj.CONST;
int max = ExampleKt.MAX;
int version = C.VERSION;

interface์˜ default method ์‚ฌ์šฉ

  • compile with -Xjvm-default=all
// compile with -Xjvm-default=all

interface Robot {
    fun move() { println("~walking~") }  // will be default in the Java interface
    fun speak(): Unit
}
//Java implementation
public class C3PO implements Robot {
    // move() implementation from Robot is available implicitly
    @Override
    public void speak() {
        System.out.println("I beg your pardon, sir");
    }
}
//Java
public class BB8 implements Robot {
    //own implementation of the default method
    @Override
    public void move() {
        System.out.println("~rolling~");
    }

    @Override
    public void speak() {
        System.out.println("Beep-beep");
    }
}

๋งํฌ