Скрытие поля INSTANCE объекта Kotlin от Java (и Kotlin) - PullRequest
2 голосов
/ 21 мая 2019

Короткий вопрос

Могу ли я изменить видимость объекта Kotlin INSTANCE (для взаимодействия Java) на internal или ниже?

Длинный вопрос

Я пишу библиотеку и хочу иметь файл / класс API , написанный на Kotlin , который предоставляет функцию для вызова из Java или Kotlin, например:

Котлин:

API.function()

Java:

API.function();

Я могу добиться этого, написав это так:

Котлин:

object API {
    @JvmStatic
    fun function() = TODO()
}

Однако теперь я тоже могу сделать это:

Java:

API.INSTANCE.function();

Я хочу запретить этот доступ к INSTANCE, чтобы свести к минимуму поверхность моего API для простоты.

Можно ли изменить видимость от INSTANCE до internal или ниже?

Вероятно, это невозможно, потому что любой вызов API (из Kotlin) возвращает экземпляр объекта, и это, вероятно, также должно быть скрыто, чтобы это было возможно. Тем не менее, мне любопытно посмотреть, если это без серьезных взломов.

Решением с использованием Java было бы написать API на Java:

public final class API {
    private API() {
    }

    public static void function() {
    }
}

Однако я ищу решение, написанное на Kotlin.

1 Ответ

2 голосов
/ 21 мая 2019

Самое близкое, что я мог придумать, было примерно так:

Создать файл API.kt в пакете com.example.api. Добавьте свои функции прямо в этот файл, например так:

@file:JvmName("API")

package com.example.api

fun function() {
    // ...
}

Котлин:

Вы можете импортировать эту функцию куда угодно, чтобы использовать свой API:

import com.example.api.function

Хотя вы не можете больше использовать свой синтаксис API.function.

Java:

Сгенерированный класс будет выглядеть примерно так (без синглтона, только статические методы, но без личного конструктора):

 public final class API {
     public static final void function() {
         // ...
     }
 }

Что позволяет затем назвать его как API.function();


Указывая @file:JvmName("API"), вы указываете котлину назвать созданный класс API.

...