Some people have spoken against Kotlin’s decision to make classes, methods, etc. public by default (when no visibility modifier is used), and I would just like to pitch in on why I think JetBrains made the right decision on this one.
Those who are against it bring up the principle of hiding everything that you can get away with in order to preserve encapsulation, and that if it’s too easy, people will make things public that shouldn’t be. I can see their point, but I don’t think it’s as likely to be to an issue as they seem to think. First off, in JetBrains’ research of Java codebases, there is between 2.5 and 5 times more uses of public than private, and I agree with Kotlin’s decision that defaulting to public makes it all that much cleaner. There’s a decent argument against this, largely stating that most of those public artifacts should be something more akin to Kotlin’s
internal modifier, but had to be public because Java’s visibility options aren’t the “right” set of options. You can read about this argument in more detail here. On the same note, you could rebuke that by saying that, really, only those classes would need to be internal while keeping their attributes public. Unless the class is inherited from from something public, that should be enough to keep other code from getting access.
If you follow that track, though, you kind of have to start down the path of maybe different things should have different defaults. Top level functions and classes would default to internal, but properties almost need to be public, since their primary use case is providing indirect public access to the fields behind them (also, having to include
public in front of a majority of properties in the primary constructor would suck; The few times I had to use
private there has been painful). To jump to the end of this line of thought, though, it seems that having different defaults for different things would end up simply being confusing, especially for newcomers to the language. This is not what we want.
My biggest issue with defaulting to
internal, though, is that (from what I can tell) it doesn’t actually have a meaning outside of Kotlin. I’m pretty sure that internal things are actually public, but they have some sort of tag with them that Kotlin uses to determine internal status. Java would simply see these as public classes, so it’s easy to work around the restrictions. I haven’t heard anything about how
internal works with Java 9+ modules, which might be proper, but Kotlin’s definition of a module is a little more flexible, I think, so I’m not sure how compatible they are. Honestly, though, I don’t know enough about either to give an educated response.
You can disagree; that’s fine. I’m just giving my 2 cents.
|Published on Java Code Geeks with permission by Jacob Zimmerman, partner at our JCG program. See the original article here: Quickie Post: Defending Public-By-Default in Kotlin|
Opinions expressed by Java Code Geeks contributors are their own.