https://kotlinlang.org logo
#getting-started
Title
# getting-started
r

Rafał Kuźmiński

12/02/2023, 6:47 PM
Hello. Is there any way to achieve same behavior in Kotlin like package-private in Java? Maybe you can recommend some plugins for Intelij? Currently I'm trying to do it with Arch Test, but it works only for JVM part and doesn't work in real time, it can only show errors after running tests. Of course I'm aware of internal modifier, but it is not the same
d

Daniel Pitts

12/02/2023, 6:48 PM
You can use
internal
which sort of means module-private .
lol, just saw your edit.
r

Rafał Kuźmiński

12/02/2023, 6:50 PM
Sure but we cannot have hundreds of modules just to keep some interface implementation from being visible. Internal is great for libraries, but in big project it is not enough
d

Daniel Pitts

12/02/2023, 6:52 PM
In reality you'd be more likely to organize it with a module-per-layer (if you have a layered architecture), in which case using internal makes sense.
Having hundreds of packages seems nearly as bad as having hundreds of modules.
r

Rafał Kuźmiński

12/02/2023, 6:55 PM
Could you elaborate? Hundreds of packages does not make me to create and maintain hundreds of build.gradle files. I could not think of any issue related to packages amount
d

Daniel Pitts

12/02/2023, 6:56 PM
I'm not talking about build overhead, but design wise that indicates extreme complexity.
If you have a monolithic project with 100 packages, it is definitely type to decompose it into separate modules. Separate projects even.
r

Rafał Kuźmiński

12/02/2023, 6:57 PM
Anyway I don't want to discuss package-private vs internal, there is huge discussion on kotlinlang.org I only wanted to ask if anyone knows some plugin for Intelij or other way to simulate this behavior. Complexity is subjective and related to specific project
d

Daniel Pitts

12/02/2023, 6:59 PM
Probably the best way is to create an
InternalApi
annotation, and mark it as
RequiresOptIn
Here is an example in the
coroutines
library:
Copy code
/**
 * Marks declarations that are **internal** in coroutines API, which means that should not be used outside of
 * `kotlinx.coroutines`, because their signatures and semantics will change between future releases without any
 * warnings and without providing any migration aids.
 */
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY)
@RequiresOptIn(
    level = RequiresOptIn.Level.ERROR, message = "This is an internal kotlinx.coroutines API that " +
            "should not be used from outside of kotlinx.coroutines. No compatibility guarantees are provided. " +
            "It is recommended to report your use-case of internal API to kotlinx.coroutines issue tracker, " +
            "so stable API could be provided instead"
)
public annotation class InternalCoroutinesApi
It doesn't prevent usage, but it strongly discourages.
Not that package-private (or even private) prevents usage if you use reflection.
r

Rafał Kuźmiński

12/02/2023, 7:03 PM
Sure but I don't care about how someone would use it, like I said I don't need this for library, just for a project. Most important thing is to hide classes from autocomplete and show compilation error if anyone would try to use them. There is a private class option, but it can be used only in single file, which is tragic for readability
d

Daniel Pitts

12/02/2023, 7:05 PM
I don't know if the RequiresOptIn hides from autocomplete, but it does show a compiler error.
Anyway, that's the best I know of.
r

Rafał Kuźmiński

12/02/2023, 7:06 PM
Sure, thank you!
2 Views