Kotlin to support package protected visibility

Yes, I also look forward to recursive package visibility

If there are so many people that are asking for a package private visibility why you just don’t implement it?
I am also a big fan of code encapsulation etc.
Maybe it is very hard or even impossible to implement that kind of visibility in Kotlin because of some architectural decisions already made and implemented in Kotlin? If not, please just do it, for the sake of the community.
The protected modifier works even better in Kotlin than in Java (protected things are not visible inside package). Ideally there could be an access visibility like local or whatever, which works as package private in Java and could be combined like local protected (the combination could work as protected in Java)

For top level elements, private is private to the file, not to the class. As such there is a way to encapsulate related code in Kotlin that is not available in Java.

I know that, but having a lot of classes in one file is not a good idea because:

  • they are hidden in the IDE’s project source tree
  • such a file can have 2000+ of lines which makes it very hard to navigate through (you will eventually get frustrated after working with that kind of file for a while)

Another thing that needs package private visibilty iin Kotlin is writting libraries.
Using internal will work well only if you are using the library in Kotlin app.
If you use Kotlin library in Java you will see all the internal classes as public ones which ruins the quality of the library API.
You can use single files with multiple classes of course…

1 Like

I don’t understand why this extreme concern against the implementation of package-visibility.

I see in this thread very good reasons why not to use them and why to use them.

No philosophy seems better than the other, the same way a knife can be used to cook or kill.

Saying that package-visibility can be misused and thus let’s not implement it, is the same as assuming every developer using Kotlin is dumb and has no idea what is doing.

Why not allow package-visibility modifiers to exist, and it boils down to the will of each developer which style he/she prefers to use.

I see very good reasons for the two philosophies and there is no way anyone in this thread is able to say that only one philosophy is the correct philosophy. And for that, I would allow this feature.

Certainly Kotlin has implemented other features that are much more “dubious” of their usefulness/correctness/requested than this feature, and there was much less (or no) obstacles to it.

2 Likes

I don’t see that in this thread. There are a few people here that don’t think package visibility is necessary for kotlin and others who argue it is. Yes AFAIK JetBrains is part of the first group (or at least they used to be), but I don’t think this can’t ever change.
There are good reasons to implement package visibility. If you guys are serious about it you should write a KEEP for it as this is the official way of changing the language. Whether it get’s approved is another question but until then nothing will change.

Basically i want my package to become my second most primitive module unit after the class itself.

Exactly. Encapsulation is Packaging. I also want to do it in Tree manner like inner package/class.

1 Like

Are all the Kotlin devs this arrogant?

6 Likes

Sorry :pensive: I was a jerk there

5 Likes

I’m missing package private too. Currently I’m planning to enforce it externally in the build pipeline with jqassistant. But that is obviously a workaround.

Thanks for mentioning jqassistant, at least we can have some clunky half-way solution to this.

I also urge Jetbrains to implement package-level visibility modifiers. It greatly enables better code organization in clean architecture/ddd/screaming architecture designs.

I’ve never heard about jqassistant but can it handle a public class with some package-private methods?
If so how can I tell jqassistant that I want some method in a Kotlin class to not be used outside the package?

I want to know how can I open class only to test class in kotlin? currently in Java class I can use package-private
First asked on https://stackoverflow.com/questions/59158369/how-can-i-open-class-only-to-test-class

1 Like

In Kotlin there’s no way for a class to have methods “more visible” to a test class than to the rest.

For the record Java isn’t really different, even if you use package visibility anyone can create a class in that package and call your package private members.

I’ve been using the Experimental API as a way to quasi-hide implementation details: https://kotlinlang.org/docs/reference/experimental.html
It’s pretty ideal for creating tags and the compiler forces you to either propagate or add a @UseExperimental for them.

I have to join the choir here.
My Java code is neatly organized into Java packages, making frequent use of package-private access as a means to hide dirty implementation details from the codebase outside the package. This is not about security, but about exposing a clean-public API’s within my own application. Modules are too coarse. Even a mid-sized project can have dozens of packages, and if I want to have the same, clean API I have in Java in Kotlin, then I would have to create a module for each package, which is a messy maintenance nightmare.
I’ve started migrating my code from Java to Kotlin, but the lack of package-private is a real dealbraker in some cases, and I have to start thinking about “hacks” like Python-style underscore “_” method and field names to remind me that this is package “internal” framework API that should not be called. Defining all sorts of types and methods in the same file using private access is a hacky workaround that is unnaceptable to me.
I see no good reason not to have package-private - it is a useful developer tool to separate “framework” API from public API within the same module.

(I’ve added my voice to the youtrack)

15 Likes

Let me give you just one use-case that highlights the good practice of using package-private access:

I have a custom annotation processor to save “data classes” to disk. The annotation processor will process classes annotated with @MyData, and generate a “SaveMyDataClass” class for it. E.g.

@MyData
class MyDataClass { ... }

Annotation Processor generates:
class SaveMyDataClass {... serializes fields in MyDataClass to file ...}

The “SaveMydDataClass” will be generated in the same package as the “MyDataClass”. And guess what… the fields in MyDataClass are all package-private, so that the Save class can process and access them, without the fields being exposed outside the package.

To achieve the same in Kotlin, I have to make the fields private and use reflection in the “Save” class, or have them all public and accessible everywhere.

This :+1:

13 Likes

It’s amazing that after all these years we still don’t have this feature. This thread has shown plenty of different examples where it is useful, but it seems as though the arguments are have not been understood.

Also, the arguments about security are not really valid, since it’s possible to circumvent it using reflection and finding the correct names of generated methods.

3 Likes

Package visibility for placing private helper classes inside API-modules like in java is just a limited way. So helper classes cannot be placed into a deeper nested package, but have to be placed beside the main-API class to archive protection from the outside world.

Much more nicer will be the “friend” concept.

https://en.cppreference.com/w/cpp/language/friend

2 Likes