JEP draft: Implicit Classes and Enhanced Main Methods (Preview)

Attila Kelemen attila.kelemen85 at gmail.com
Wed Apr 5 21:51:38 UTC 2023


Forwarding my email from "amber-spec-observers" to
"amber-spec-comments", since I just realized that this is the more
appropriate list. See my original email below:


Hi,

Apologies for not responding properly to the chain, but I was not
subscribed to this list before. Still, I read the archives, and
hopefully didn't miss much.

I generally like the goal of the JEP. At the very least, less mocking
from people often citing how "difficult" it is to write a
"Hello World" :). Regardless, I would like to propose a generalization
that is useful in more contexts, and then this issue could be
separated into multiple JEPs.

Instead of merely making this a special case for main classes, there
could be a JEP to declare utility classes in an easier way (because
utility classes have their - well - utility). This is how it would
work:

## JEP X1 - Convenient Utility Classes

- The convenient utility Java file would be detected by having a
  method without an enclosing class (like this JEP).

- An enclosing class is assumed with the same name as the file name
  (without .java of course).

- The generated enclosing class is declared final, and does not have
  a callable constructor, not even from the same file (javac could
  still generate a private one throwing `AssertionError`).

- Every top level declaration (method, field, class, etc.) is
  implicitly static (just like it is the case for interface fields).

- The visibility of the generated enclosing class is the visibility
  of the top level entity with the highest visibility.

- The method named "main" cannot be overloaded. I'm guessing this is
  highly controversial, because this changes the language in these
  kind of files. But I would argue that the method named "main" is
  special enough to warrant this treatment, because if we consider
  beginners, then their main issue is making a mistake and not
  getting a helpful error message. If they were to accidentally
  declare a "main" method with the wrong signature (or left an old
  one which is a preferred one, if we allow multiple kinds of main
  methods), then it might confuse them that their method is not
  being called. Also, restricting overload would allow future
  possibilities for convenience.

- Related to the previous: The method named "main" must have a
  correct signature (= declares a valid entry point).


I have read Brian's argument against static, but that would not apply
here, because copy-pasting something with "static" modifier would
still be fine, just redundant. The only thing that would not work
is the `this` reference, but I would argue that `this` is quite
misleading anyway for someone who does not have the concept of
classes, and is also rare in example codes, unless the example code
only meaningful with a class.

The idea of "main" in abstract classes would not come automatically
with this proposal, but it does not prevent another JEP from
introducing that possibility.

There are multiple benefits of this approach:

- Before introduced to classes, students can still "modularize" their
  code into separate files.

- Useful for non-students as well to declare utility methods.

- Does not require a change in the way java detects (and calls) entry
  points. Such changes can be done in an independent JEP.


## JEP X2 - Flexible main arguments

This JEP would only apply to classes in JEP X1. If a method named
"main" have different parameter list than `(String[])`, then a new
`static void main(String[])` method is generated by javac which calls
the explicitly declared one with the appropriate arguments.

I don't want to specify now what are "appropriate" arguments, but
I'm thinking alongside the following examples:

- (): Obviously, this is trivial to call.
- (String): Passed `(args[0])`.
- (String, int): Passed `(args[0], Integer.parseInt(args[1]))`

In all cases, there should be a strict argument check done with a
helpful error message. The strict argument check would require an
exact match on the number of arguments. That is, if the explicitly
declared "main" has the arguments `(String, String)`, then passing 3
or more arguments is an error.

The error should be reported by throwing an exception (preferably with
at most one line of stack trace).


## JEP X3 - Non-public main methods

As simple as that: Allow java to call a "main" method with any
visibility as an entry point.


What do you think about these proposals?

Thanks,
Attila


More information about the amber-spec-comments mailing list