Simplified main methods -- what IDE users should expect?

Brian Goetz brian.goetz at oracle.com
Thu May 8 12:57:35 UTC 2025


Thanks for starting this discussion.  Indeed, I think it is good to have 
a fresh look at an empty IDE window, and see where we think it should go.

First, I think the "but everyone knows public static void main, so we 
should keep it that way forever" argument is a bit silly.  We should 
guide people towards the best version of the language; many developers 
learn a lot about Java from the hints provided by the IDE.

Let's skip over the "what should the defaults be" for a second, and talk 
about refactoring between the various versions.  IDEA already has hints 
for when `public` is unnecessary, such as the public modifier on 
instance methods.  It renders `public` in a lighter tone and offers a 
quick-fix to drop it.  It seems reasonable to do the same with `public` 
on main?  Similarly, if the class already has a no-arg constructor (or 
perhaps has _no_ explicit constructor, or an empty no-arg constructor), 
it can do the same with `static`, offering to vanish it for the user.  
And with `String[] args`, if `args` is not used in the body, it can do 
the same with those.

So separate from the question of defaults, a class with p-s-v-m that 
doesn't need public, static, or args, the IDE can guide us to a more 
minimal version of main.  That seems nice.  Similarly, for an instance 
main, or a main without args, I assume there will be quickfixes offered 
to add back `args` or `static`, in case the minimal main is not what the 
user wants.  With all this in place, even if the default is wrong, it is 
easy to incrementally navigate up and down to the "smaller" or "bigger" 
declaration as desired.

I think your starting position of "no public" and "no args" is good.  I 
like your story about "guessing" whether the user wants an `args` 
variable; another possible heuristic, besides going strictly by name, is 
whether they use an undeclared array variable (such as on the RHS of 
foreach, or x.length, or x[i]), and offer a "was that supposed to be the 
arguments?" quickfix.

Also, since there can now be multiple possible main candidates, I think 
another thing the IDE can help with is identifying when a method called 
`main` is _not_ the main method that the launcher will invoke.  (The 
"real" main method may be in a superclass now.)

Static is the hard one.  "Instance main" is the least well known aspect 
of this JEP; it is hard to tell whether the community will adopt it as 
their default (I suspect some will, some won't, and there will be 
low-grade style wars about it.)

> We cannot generate `void main(){}` inside the class that contains no 
> default constructor, as this method will be non-functional and users 
> might be surprised and confused.

By "default constructor", you mean no-arg, right?  Because if you have 
_no_ explicit constructor, you get a free no-arg constructor, and are fine.

> I lean toward generating 'static' by default for explicit classes 
> (regardless of its constructors) and no 'static' for implicit classes. 
> However, I'm not sure that it's the best solution.

I think that's an OK starting point, but I might suggest to nudge you 
over into dropping the static if the class is sufficiently "empty" (no 
ctors, empty no-arg ctor, etc.)  I think there might be momentary 
confusion about "where's my static", but if so, that's a one-time 
learning opportunity, and thereafter it will be fine.

As to `psvm`, my first thought is to keep psvm as is, for people who are 
used to it, but then the psvm declaration will immediately have dimmed 
out `public`, `static`, and `String[] args`, so users will see these are 
optional and may take the quickfixes to drop them.  And then have 
another macro for `main` (which is easier to remember anyway) that is 
the "smart main wizard" that declares the main method using the minimal 
set of gunk relative to context, being sensitive to the presence of an 
explicit class declaration or not, explicit ctors or not, etc.  But I 
can also see how it is nice to just guide people to the new Java with 
the old name.  So I think either way works here.

Stepping back a step, I always get a new class window with ctrl-N, which 
asks me for a class name and fills in `public class Foo` for me.  Will 
the "new class" dialog have an option for "implicit class"?  (And, what 
do we call it?  The spec term "implicit class" will not necessarily be 
helpful to the target audience, since they may not know that's what they 
want.  Perhaps some sort of "new single file program" option?)






On 5/8/2025 4:32 AM, Tagir Valeev wrote:
> Hello, dear experts!
>
> This discussion is not exactly about Java specification, but I think 
> we have the right people here for this topic.
>
> The Java IDEs usually provide a way to automatically generate a main 
> method using some kind of template named 'main' or 'psvm' (which is 
> short for 'public static void main'). Historically, invoking such a 
> template generated a code like this:
>
> public static void main(String[] args) {
>   <caret is here>
> }
>
> However, when 'Compact Source Files and Instance Main Methods' feature 
> (JEP 512) is available, this doesn't look like a good default anymore. 
> Some of our colleagues advocate that keeping the old signature is good 
> because this is what people get used to, but I think we should 
> reconsider this.
>
> Now we have multiple ways to generate a main method:
> - 'public' may be present or not
> - 'static' may be present or not
> - 'String[] args' may be present or not
>
> So technically we have eight different variants. What would the user 
> expect by default?
>
> In my opinion, 'public' is simple: we should just drop it, as it 
> doesn't add any value. This reduces the number of options to four.
>
> The 'static' modifier is more difficult. 'static void main()' and 
> 'void main()' have different semantics: the latter involves automatic 
> class instantiation, it makes the main() method inheritable (so 
> inheritors if any may become launchable), and it requires a no-arg 
> constructor. We cannot generate `void main(){}` inside the class that 
> contains no default constructor, as this method will be non-functional 
> and users might be surprised and confused. We might consider adding 
> the `static` modifier only in classes without no-arg constructor, but 
> this might be inconsistent, as users might not understand why 
> sometimes `static` is generated and sometimes is not. Another case is 
> implicit classes where `static` looks really alien, and we never have 
> problems like no-arg constructors or inheritors. So I lean toward 
> generating 'static' by default for explicit classes (regardless of its 
> constructors) and no 'static' for implicit classes. However, I'm not 
> sure that it's the best solution.
>
> Skipping 'String[] args' by default seems nice, but it will worsen the 
> experience of people who actually need the args, as they will probably 
> need to type more. We can assume that the variable named 'args' is 
> implicitly available inside the method body, so the user may use it 
> via autocompletion, and upon the first use, it will be automatically 
> added to the method signature. This is possible but somewhat weird: 
> users should know in advance that something named 'args' can be used, 
> even if it's not explicitly available in the code.
>
> We can also create several templates (something like 'maina' for main 
> with arguments and 'mains' for static main), but this also complicates 
> things and increases the cognitive load to the users. Also, different 
> IDEs may solve this differently, and this may add confusion for people 
> who change IDE sometimes.
>
> I would be glad to hear your opinions. What would you expect from your 
> IDE when generating a main method in Java 25?
>
> With best regards,
> Tagir Valeev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20250508/05d3cd56/attachment-0001.htm>


More information about the amber-spec-experts mailing list