This question came up in a few different forms, but there's a reason why
I've only relaxed the "must be public" for classes in the unnamed
package: security.
There may be existing classes with a package-private instance main()
method, and they may have reasonably assumed that these are only
callable from within the package. If the launcher can barge in and open
non-public classes and call non-public methods, that may be surprising.
Restricting the "main can be non public" to the unnamed package is
justifiable because we can reasonably treat the launcher as being part
of the unnamed package (and therefore this rule falls out from ordinary
access control) and because it is disadvised to distribute libraries
that use the unnamed package, reserving it instead for local
experimentation.
Framing the launcher as "just some Java code in the unnamed package"
also demystifies the launcher a bit.
On 9/28/2022 3:49 PM, Kevin Bourrillion wrote:
- Relax the requirement that the class, and `main` method, be
public. Public
accessibility is only relevant when access crosses packages;
simple programs
live in the unnamed package, so cannot be accessed from any
other package
anyway. For a program whose main class is in the unnamed
package, we can
drop the requirement that the class or its `main` method be public,
effectively treating the `java` launcher as if it too resided
in the unnamed
package.
Alternative: drop the requirement altogether. Most main methods have
no desire to make themselves publicly callable as
`TheClass.main(args)`, but today they are forced to expose that API
anyway. I feel like it would still be conceptually clean to say that
`public` is really about whether other *code* can access it, not
whether a VM can get to it at all.