7

Short question

Can I modify the visibility of a Kotlin object's INSTANCE (for Java interop) to internal or lower?

Long question

I'm writing a library and I want to have an API file / class, written in Kotlin, that exposes a function to be called from either Java or Kotlin like this:

Kotlin:

API.function()

Java:

API.function();

I can achieve this by writing it like this:

Kotlin:

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

However, now I can also do this:

Java:

API.INSTANCE.function();

I want to prevent this access to INSTANCE to keep my API surface to a minimum for simplicity.

Can I modify the visibility of INSTANCE to internal or lower?

It's probably not possible, because any call to API (from Kotlin) returns the object's instance and that should probably be hidden too for this to be possible. However, I'm curious to see if it is without major hacks.

A solution using Java would be to write API in Java:

public final class API {
    private API() {
    }

    public static void function() {
    }
}

However, I'm looking for a solution written in Kotlin.

2
  • Have you considered writing interface in Java and implementation in Kotlin? Commented May 21, 2019 at 12:04
  • I think you didn't want an object (~singleton) in the first place (maybe you had a Utilitity-class in mind, because that's the only way to support such functions in Java? ;-)), but rather a set of functions accessible via a common interface... Linos answer shows you that and it will be wrapped to what you are comfortable with on the Java side... Commented May 21, 2019 at 12:11

1 Answer 1

7

The closest I could come up with was something like this:

Create a file API.kt in a package com.example.api. Add your functions directly into that file, like this:

@file:JvmName("API")

package com.example.api

fun function() {
    // ...
}

Kotlin:

You can import that function anywhere you need to use your api:

import com.example.api.function

Though you can't use your syntax API.function anymore.

Java:

The generated class would look something like this (no singleton, just static methods, but no private constructor):

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

Which then allows you to call it like API.function();


By specifiying @file:JvmName("API") you instruct kotlin to name the created class API.

Sign up to request clarification or add additional context in comments.

1 Comment

Amazing! finally we can have fully static classes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.