Вы когда-нибудь пытались понять, почему метод main() в Java является публичным, статическим и недействительным? Почему его имя main? Что происходит внутри JVM, когда вы вызываете метод main()? Каково назначение метода main? Давайте выясним.
Начиная с Java 21, мы можем создавать методы экземпляра main(), которым не требуются модификаторы доступа public и static, а аргументы метода являются необязательными.
Если мы не создали безымянный класс, обсуждение в этой статье все равно применимо.
1. Синтаксис метода Java main()
Начнем с напоминания синтаксиса метода main в Java.
public class Main{public static void main(String[] args){System.out.println("Hello World !!");}}
2. Почему метод main в Java является публичным?
Это большой вопрос и, возможно, самый сложный для ответа. Я изо всех сил старался найти вескую причину для этого вопроса во всех хороших учебных материалах, которые были мне доступны, но ничего не оказалось достаточным.
Итак, мой анализ говорит(как и многие другие): основной метод является публичным, чтобы он был доступен отовсюду и каждому объекту, который может пожелать использовать его для запуска приложения.
Здесь я не говорю, что у JDK/JRE была точно такая же причина, поскольку java.exe или javaw.exe(для Windows) могут использовать Java Native Interface(JNI) для выполнения метода invoke для вызова метода main(), поэтому они могли вызвать его любым способом, независимо от любого модификатора доступа.
Второй способ ответить на это — другой вопрос, почему не public? Все методы и конструкторы в java имеют какой-либо модификатор доступа. Методу main() он тоже нужен. Нет причин, по которым он не должен быть public и не иметь любого другого модификатора(default/protected/private).
Обратите внимание, что если мы не сделаем метод main() публичным, ошибки компиляции не будет. Вы получите ошибку времени выполнения, поскольку соответствующий метод main() отсутствует. Помните, что весь синтаксис должен совпадать для выполнения метода main().
public class Main{void static main(String[] args){System.out.println("Hello World !!");}}
Вывод программы:
Error: Main method not found in class Main, please define the main method as:public static void main(String[] args)
3. Почему статичный?
Еще один большой вопрос. Чтобы понять это, предположим, что у нас нет основного метода как статического. Теперь, чтобы вызвать любой метод, вам нужен его экземпляр. Правильно?
Java может иметь перегруженные конструкторы, мы все знаем. Теперь, какой из них следует использовать, и откуда будут браться параметры для перегруженных конструкторов. Это просто более сложные вопросы, которые помогли разработчикам Java определиться и сделать метод main статическим.
Обратите внимание, что если вы не сделаете метод main() статическим, то ошибки компиляции не будет. Будет ошибка времени выполнения.
public class Main{public void main(String[] args){System.out.println("Hello World !!");}}
Вывод программы:
Error: Main method is not static in class main, please define the main method as:public static void main(String[] args)
4. Почему аннулирование?
Почему он не должен быть void? Вы вызывали этот метод из своего кода? НЕТ. Тогда нет смысла возвращать какое-либо значение JVM, которая фактически вызывает этот метод. Ему просто не нужно возвращать какое-либо значение.
Единственное, что приложение хотело бы сообщить вызывающему процессу, это нормальное или ненормальное завершение. Это уже возможно с помощью System.exit(int). Ненулевое значение означает ненормальное завершение, в противном случае все было бы нормально.
5. Почему название является основным?
Нет никакой весомой причины. Предположим, потому что это уже использовалось в языках C и C++. Поэтому большинство разработчиков уже были довольны этим именем.
В противном случае других веских причин нет.
6. Что происходит внутри при вызове метода main?
Цель метода main в Java — служить начальной точкой выполнения программы.
Когда вы запускаете java.exe, происходит несколько вызовов Java Native Interface(JNI). Эти вызовы загружают DLL, которая на самом деле является JVM(именно так — java.exe — это НЕ JVM). JNI — это инструмент, который мы используем, когда нам нужно навести мосты между миром виртуальных машин и миром C, C++ и т. д. Обратное тоже верно. Невозможно на самом деле запустить JVM без использования JNI.
По сути, java.exe — это очень простое приложение на языке C, которое анализирует командную строку, создает новый массив строк в JVM для хранения этих аргументов, анализирует указанное вами имя класса, содержащего main(), использует вызовы JNI для поиска самого метода main(), а затем вызывает метод main(), передавая в качестве параметра вновь созданный массив строк.
Это очень, очень похоже на то, что вы делаете, когда используете отражение из Java, просто вместо этого используются запутанно названные собственные вызовы функций.
Вы совершенно законно можете написать свою собственную версию java.exe(исходный код распространяется вместе с JDK) и заставить ее делать что-то совершенно иное.
7. Метод main(), собственный код в java.c
Загрузите и распакуйте исходный jar-файл и проверьте ../launcher/java.c. Это что-то вроде этого:
/** Get the application's main class.*/if(jarfile != 0) {mainClassName = GetMainClassName(env, jarfile);... ...mainClass = LoadClass(env, classname);if(mainClass == NULL) { /* exception occured */... .../* Get the application's main method */mainID =(*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");... ...{/* Make sure the main method is public */jint mods;jmethodID mid;jobject obj =(*env)->ToReflectedMethod(env, mainClass, mainID, JNI_TRUE);... .../* Build argument array */mainArgs = NewPlatformStringArray(env, argv, argc);if(mainArgs == NULL) {ReportExceptionDescription(env);goto leave;}/* Invoke main method. */(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
Итак, здесь вы можете увидеть, что происходит при вызове Java-программы с методом main.
8. Резюме
Основной метод Java используется всеми разработчиками, и все знают базовый синтаксис для его написания. Однако очень немногие полностью понимают правильные рассуждения и то, как это работает.
В этой статье мы получили очень общее представление о том, что лежит в основе основного метода, который является основной отправной точкой приложения.
Приятного обучения!!