Первый урок - или трюк, в зависимости от того, как вы на него смотрите, - этот вопрос заключается в том, что только один main
метод является особенным, независимо от того, сколько существует main
методов. Особый - тот, который принимает форму
public static void main( /* multiple arguments */ ) { ... }
В прошлом аргумент должен был быть String[] args
, но для последних версий также допустимы var-args (например, String... args
). JLS 12.1.4
Теперь, когда мы знаем, с какого метода начинать, мы видим, что первая строка проверяет значение a
. Мы видим, что он инициализирован в 1, поэтому мы можем игнорировать строку a==2
. Затем на следующей строке мы переходим к аргументу без аргументов main
.
В no-arg main
значение a
устанавливается равным 2. Следующий урок заключается в том, что локальные переменные метода могут скрывать переменные класса. Новый a
объявляется, и он имеет приоритет внутри метода, но живет только столько, сколько метод. Это массив строк размером десять, но устанавливается только первая («Hi2»). У этого метода есть еще один урок: этот код написан, чтобы заставить вас думать, что строка-аргумент main
вызывается следующим, но это не так, потому что мы не создали объект и это не static
. Вместо этого мы возвращаемся к main(String[] args)
.
На этот раз a
равно 2 - запомните, мы установили его в no-arg main
, а a
- static
, поэтому изменение остается неизменным - поэтому мы печатаем первый аргумент "Hi2. " Затем мы устанавливаем a
на 3, поэтому предстоящий тест a==1
не пройден. В следующей строке мы печатаем «Hi1» в первый раз и создаем новый экземпляр PlayingWithMain
, который, как я полагаю, является классом, в котором живет весь фрагмент кода.
Поскольку a
равно static
, его значение остается равным 3 даже для нового объекта. Однако, поскольку объект вызывает main("Hi3")
, мы не переходим к static
версии main
; вместо этого мы переходим к строке-arg main
. Этот метод просто отправляет ввод обратно вызывающей стороне, где он немедленно распечатывается.
Это делает это для string-array-arg main
, поэтому мы возвращаемся к методу, который его вызвал, no-arg main
. Это также закончено, поэтому мы снова возвращаемся к версии main(String[] args)
, которую назвала JVM. Помните, мы только что завершили линию
if (a==1) { main(); }
поэтому мы снова переходим к печати «Hi1». Наконец, мы повторяем последнюю строку, которая создает еще один новый PlayingWithMain
объект и печатает «Hi3» в последний раз.