Thank you for your thoughts on this topic! > By "default constructor", you mean no-arg, right?
Yes, shame on me. Sometimes I mix 'default constructor' (an implicit one) and an explicit no-arg constructor. We already dim the args parameter in the main() if it's not used and the language level allows omitting it. In future versions, we will dim public or protected on main if it's not called from anywhere (though sometimes searching the callers in the interactive editor in a huge project could be costly). We are still not sure whether we want to have different behavior for 'psvm' and 'main' templates, as so far they were synonymous. Also, in Kotlin, we also have 'psvm' which generates simply `fun main() {}` and people do not complain. There's also 'main' template which does the same, so probably people without Java background are simply unaware about 'psvm'. We are still not so sure about 'static' being redundant. We will mark it as such in implicit classes, but probably not yet in normal classes. With best regards, Tagir Valeev. On Thu, May 8, 2025 at 3:06 PM Brian Goetz <brian.go...@oracle.com> wrote: > > 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 > >