Отметьте забаву / свойство для использования только в Kotlin / Java - PullRequest
2 голосов
/ 19 июня 2020

В настоящее время я пишу класс KOTLIN, где я хотел бы использовать возможности DSL, но быть обратно совместимым для разработчиков JAVA. При использовании var компилятор автоматически создает геттер и сеттер для JAVA, но их нельзя использовать в стиле Builder, так как они не возвращают this.

Итак, в основном то, что мне нравится делать, это примерно так:

class MyClass {
    // for use in KOTLIN only DSL style e.g. MyClass() { offset = 1 }
    var offset: Int? = null

    // for use in JAVA only BUILDER style e.g. new MyClass().withOffset(1)
    fun withOffset(value: Int) = apply { offset = value }
}

В Kotlin Мне нравится использовать, но не хочу иметь доступ к withOffset развлечениям:

val myClass = MyClass() { offset = 1 }

В JAVA Мне нравится использовать, но не хочу иметь доступ к автоматически созданным setOffset и getOffset:

MyClass myClass = new MyClass().withOffset(1)

Переименование получателя и сеттера уже возможно через аннотацию @JvmName, но это возможно. есть аннотация для того, чтобы скрыть свойство publi c для JAVA полностью и необязательно, конечно, наоборот?

Ответы [ 2 ]

2 голосов
/ 19 июня 2020

Вы не можете скрыть конструктор, в то время как вы можете создать так называемый поддельный конструктор, используя operator fun invoke, в котором вы можете использовать аннотацию @ JvmSynthei c, чтобы скрыть его из java.

И чтобы скрыть функцию из kotlin, вы можете использовать @ Deprecated с DeprecationLevel.HIDDEN .

Примечание: @ JvmField укажет компилятору не создавать геттер и сеттер по умолчанию для вашей переменной

class MyClass {
    @JvmField
    var offset: Int? = null

    @kotlin.Deprecated(message = "JUST FOR JAVA", level = DeprecationLevel.HIDDEN)
    fun withOffset(value: Int) = apply { offset = value }

    companion object {
        @JvmSynthetic
        operator fun invoke(init: MyClass.() -> Unit) = MyClass().apply(init)
    }
}

Использование в kotlin:

MyClass() { offset = 1 }
// or
MyClass { offset = 1 }

Использование in java:

MyClass().withOffset(1)

Ресурсы:

1 голос
/ 19 июня 2020

Невозможно сделать что-то подобное в Kotlin

val myClass = MyClass() { offset = 1 }

, но я бы посоветовал вам сделать это вместо этого, на мой взгляд это выглядит намного лучше.

// It's a inline function so there's no runtime overhead.
inline fun buildMyClass(builder: MyClass.() -> Unit): MyClass {
    return MyClass().apply(builder)
}

class MyClass {

    @JvmSynthetic
    var offset: Int? = null
        private set

    fun withOffset(value: Int) = apply { offset = value }
}

Таким образом, вы можете назвать это, как показано ниже

val myClass = buildMyClass {
   withOffset(0)
}

В Java это выглядит так:

final MyClass myClass = new MyClass().withOffset(0);
...