Подпись метода метода Java main():
public static void main(String[] args){
...
}
Есть ли причина, почему этот метод является статическим?
Подпись метода метода Java main():
public static void main(String[] args){
...
}
Есть ли причина, почему этот метод является статическим?
Метод статичен, потому что в противном случае была бы двусмысленность: какой конструктор должен быть вызван? Особенно, если ваш класс выглядит следующим образом:
public class JavaClass{
protected JavaClass(int x){}
public void main(String[] args){
}
}
Должен ли JVM вызывать new JavaClass(int)
? Что он должен передать для x
?
Если нет, должен ли JVM создавать экземпляр JavaClass
без запуска какого-либо метода конструктора? Я думаю, что это не должно, потому что это будет особый случай для всего вашего класса - иногда у вас есть экземпляр, который не был инициализирован, и вы должны проверить его в каждом методе, который можно было бы назвать.
Слишком много крайних случаев и двусмысленностей, чтобы иметь смысл, чтобы JVM должен был создать экземпляр класса до вызова точки входа. Вот почему main
является статическим.
Я понятия не имею, почему main
всегда отмечен public
, хотя.
Это просто соглашение. На самом деле даже имя main() и переданные аргументы являются чисто условными.
Когда вы запускаете java.exe(или javaw.exe в Windows), на самом деле происходит несколько вызовов Java Native Interface (JNI). Эти вызовы загружают DLL, которая на самом деле является JVM (это право - java.exe НЕ является JVM). JNI - это инструмент, который мы используем, когда нам приходится соединяться между миром виртуальной машины и миром C, С++ и т.д. Обратное также верно - невозможно (по крайней мере, насколько мне известно) фактически получить JVM работает без использования JNI.
В принципе, java.exe - это супер простое приложение C, которое анализирует командную строку, создает новый массив String в JVM для хранения этих аргументов, анализирует имя класса, указанное вами как содержащее main(), использует вызовы JNI для поиска самого метода main(), затем вызывает метод main(), передавая вновь созданный строковый массив в качестве параметра. Это очень, очень похоже на то, что вы делаете, когда используете отражение от Java - вместо этого вместо него используются только запутанные вызовы собственных функций.
Для вас было бы совершенно законно написать собственную версию java.exe(источник распространяется вместе с JDK) и сделать что-то совершенно другое. Фактически, это то, что мы делаем со всеми нашими приложениями на основе Java.
Каждый из наших приложений Java имеет свою собственную пусковую установку. В первую очередь мы делаем это, чтобы получить собственное имя и имя процесса, но оно пригодится в других ситуациях, когда мы хотим сделать что-то помимо обычного вызова main(), чтобы добиться успеха (например, в одном случае мы делаем COM, и мы фактически передаем дескриптор COM в main() вместо строкового массива).
Итак, длинный и короткий: причина, по которой он статичен, - это b/c, что удобно. Причина, по которой она называется "главная", заключается в том, что она должна быть чем-то, а main() - это то, что они делали в старые времена C (и в те дни имя функции было важно). Я полагаю, что java.exe может позволить вам просто указать полное имя основного метода, а не просто класс (java com.mycompany.Foo.someSpecialMain), но это просто усложняет работу с IDE, запускаемых "классов в проекте.
Метод main() в С++, С# и Java является статическим, потому что он может быть вызван механизмом выполнения, не создавая экземпляр родительского класса.
Именно так разработан Java-язык, и Java Virtual Machine спроектирована и написана.
Отъезд Глава 12 Выполнение - Раздел 12.1.4 Вызов Test.main:
Наконец, после завершения инициализации для класса Test (во время которого могла произойти другая последующая загрузка, связывание и инициализация), вызывается метод main теста.
Основной метод должен быть объявлен public, static и void. Он должен принять единственный аргумент, который представляет собой массив строк. Этот метод может быть объявлен как
public static void main(String[] args)
или
public static void main(String... args)
Ознакомьтесь с Глава 2 Концепции языка Java-программирования - Раздел 2.17 Выполнение:
Виртуальная машина Java начинает выполнение, вызывая основной метод метода определенного класса и передавая ему единственный аргумент, который представляет собой массив строк. Это заставляет загружать указанный класс (§2.17.2), связанный (§2.17.3) с другими типами, которые он использует, и инициализируется (§2.17.4). Основной метод должен быть объявлен public, static и void.
Загрузите и извлеките исходную банку и посмотрите, как написана JVM, проверьте ../launcher/java.c
, который содержит собственный код C за командой java [-options] class [args...]
:
/*
* Get the application main class.
* ... ...
*/
if (jarfile != 0) {
mainClassName = GetMainClassName(env, jarfile);
... ...
mainClass = LoadClass(env, classname);
if(mainClass == NULL) { /* exception occured */
... ...
/* Get the application 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);
... ...
Пусть просто притворяется, что static
не требуется в качестве точки входа приложения.
Класс приложения будет выглядеть следующим образом:
class MyApplication {
public MyApplication(){
// Some init code here
}
public void main(String[] args){
// real application code here
}
}
Различие между кодом конструктора и методом main
необходимо, потому что в OO говорят, что конструктор должен только убедиться, что экземпляр инициализирован правильно. После инициализации экземпляр может использоваться для предполагаемой "службы". Ввод полного кода приложения в конструктор испортит это.
Таким образом, этот подход заставил бы три различные контракты на приложение:
main
1. Хорошо, это не удивительно.abstract
. В противном случае JVM не смог бы создать экземпляр.С другой стороны, для подхода static
требуется только один контракт:
main
1.Здесь ни abstract
, ни несколько конструкторов не имеют значения.
Поскольку Java был разработан как простой язык для пользователя, неудивительно, что и точка входа приложения была спроектирована простым способом с использованием контракта один, а не сложным способом, используя < сильные > три независимые и хрупкие контракты.
Обратите внимание: этот аргумент не о простоте внутри JVM или внутри JRE. Этот аргумент о простоте для пользователя.
Если это не так, какой конструктор следует использовать, если их больше?
Более подробная информация о инициализации и выполнении программ Java доступна в Спецификация языка Java.
В противном случае ему понадобится экземпляр объекта, который будет выполнен. Но его нужно вызывать с нуля, не создавая сначала объект, поскольку обычно задача функции main() (bootstrap) заключается в анализе аргументов и построении объекта, обычно с использованием этих параметров/параметров программы.
Прежде чем вызывается основной метод, объекты не создаются. Наличие ключевого слова static означает, что метод можно вызвать без создания каких-либо объектов.
В чем смысл public static void main(String args[])
?
public
- спецификатор доступа, означающий, что любой пользователь может его получить/вызвать, например JVM (виртуальная машина Java. static
позволяет вызвать main()
до того, как объект класса был создан. Это необходимо, потому что main()
вызывается JVM до того, как будут созданы какие-либо объекты. Поскольку он является static, он может быть вызван непосредственно через класс.
class demo {
private int length;
private static int breadth;
void output(){
length=5;
System.out.println(length);
}
static void staticOutput(){
breadth=10;
System.out.println(breadth);
}
public static void main(String args[]){
demo d1=new demo();
d1.output(); // Note here output() function is not static so here
// we need to create object
staticOutput(); // Note here staticOutput() function is static so here
// we needn't to create object Similar is the case with main
/* Although:
demo.staticOutput(); Works fine
d1.staticOutput(); Works fine */
}
}
Аналогично, мы используем static sometime для пользовательских методов, поэтому нам не нужно создавать объекты.
void
указывает, что объявленный main()
метод
не возвращает значение.
String[] args
указывает единственный параметр в методе main()
.
args
- параметр, который содержит массив объектов типа класса String
.
Позвольте мне объяснить эти вещи гораздо проще:
public static void main(String args[])
Все приложения Java, за исключением апплетов, начинают свое выполнение с main()
.
Ключевое слово public
- это модификатор доступа, который позволяет вызывать элемент извне класса.
static
используется, потому что позволяет вызывать main()
без необходимости создавать экземпляр определенного экземпляра этого класса.
void
указывает, что main()
не возвращает никакого значения.
Созданы апплеты, мидлеты, сервлеты и beans различных типов, а затем на них наложены методы жизненного цикла. Вызов main - это все, что когда-либо делается для основного класса, поэтому нет необходимости, чтобы состояние удерживалось в объекте, который вызывается несколько раз. Это вполне нормально, чтобы вывести основной объект в другой класс (хотя это и не очень хорошая идея), что помешало бы использовать класс для создания основного объекта.
Это просто конвенция, но, вероятно, более удобная, чем альтернатива. С помощью статической основы все, что вам нужно знать для вызова программы Java, - это имя и местоположение класса. Если он не был статичным, вам также нужно было бы знать, как создать экземпляр этого класса или потребовать, чтобы класс имел пустой конструктор.
Если основной метод не будет статическим, вам нужно будет создать объект вашего основного класса вне программы. Как вы хотите это сделать?
Когда вы выполняете виртуальную машину Java (JVM) с помощью команды java
,
java ClassName argument1 argument2 ...
Когда вы выполняете свое приложение, вы указываете его имя класса в качестве аргумента для команды java, как указано выше
JVM пытается вызвать основной метод указанного класса
- в этот момент никаких объектов класса не было создано.
Объявление
main
как статическогоallows
JVM кinvoke
mainwithout
созданию ainstance
для класса.
вернитесь к команде
ClassName
является command-line argument
для JVM, который сообщает ему, какой класс выполнить. Следуя ClassName, вы также можете указать list of Strings
(разделенные пробелами) в качестве аргументов командной строки, которые JVM будет передавать вашему приложению. -Используются такие аргументы, чтобы указать параметры (например, имя файла) для запуска приложения - вот почему в главном2 > есть параметр String[] args
Ссылки: Java ™ Как программировать (ранние объекты), десятое издание
Я думаю, что ключевое слово "static" делает основной метод методом класса, а методы класса имеют только одну его копию и могут быть разделены всеми, а также не требуют объекта для ссылки. Поэтому, когда класс драйвера скомпилирован, можно вызвать основной метод. (Я просто на уровне алфавита java, извините, если я ошибаюсь)
main() является статическим, потому что; в этот момент жизненного цикла приложения стек приложения является процедурным по своей природе из-за отсутствия объектов, которые еще не созданы.
Это чистый сланец. Ваше приложение работает на этом этапе, даже без объявления каких-либо объектов (помните, существуют процедурные шаблоны кодирования AND OO). Вы, как разработчик, превращаете приложение в объектно-ориентированное решение, создавая экземпляры ваших объектов и в зависимости от кода, скомпилированного внутри.
Объектно-ориентированная версия отлично подходит для миллионов очевидных причин. Однако не прошли те дни, когда большинство разработчиков VB регулярно использовали в своем коде ключевые слова, такие как "goto". "goto" - это процедурная команда в VB, которая заменяется ее эквивалентом OO: вызов метода.
Вы также можете посмотреть статическую точку входа (main) как чистую свободу. Если бы Java была достаточно различной, чтобы создать экземпляр объекта и представить вам только этот экземпляр, у вас не будет выбора, НО писать процедурное приложение. Как немыслимо, как это может показаться для Java, возможно, существует много сценариев, которые требуют процедурных подходов.
Это, вероятно, очень неясный ответ. Помните, что "класс" - это всего лишь совокупность взаимосвязанного кода. "Экземпляр" - изолированное, живое и дыхательное автономное поколение этого класса.
Протоип public static void main(String[])
- это соглашение, определенное в JLS:
Основной метод должен быть объявлен public, static и void. Он должен указать формальный параметр (§8.4.1), объявленным типом которого является массив String.
В спецификации JVM 5.2. Запуск виртуальной машины можно прочитать:
Виртуальная машина Java запускается путем создания начального класса, который указан зависимым от реализации образом, с использованием загрузчика класса загрузки (§5.3.1). Затем виртуальная машина Java связывает исходный класс, инициализирует его и вызывает метод открытого класса void main (String []). Вызов этого метода приводит к дальнейшему выполнению. Выполнение инструкций виртуальной машины Java, составляющих основной метод, может привести к связыванию (и, следовательно, созданию) дополнительных классов и интерфейсов, а также вызову дополнительных методов.
Забавно, что в спецификации JVM не упоминается, что основной метод должен быть статичным. Но спецификация также говорит, что виртуальная машина Java выполняет 2 шага раньше:
Инициализация класса или интерфейса состоит в выполнении его метода инициализации класса или интерфейса.
Определен метод инициализации класса или интерфейса :
Класс или интерфейс имеет не более одного метода инициализации класса или интерфейса и инициализируется (§5.5), вызывая этот метод. Метод инициализации класса или интерфейса имеет специальное имя
<clinit>
, не принимает аргументов и недействителен.
И метод класса или интерфейса инициализации отличается от метода инициализации экземпляра , как указано ниже:
На уровне виртуальной машины Java каждый конструктор, написанный на языке программирования Java (JLS §8.8), появляется как метод инициализации экземпляра, который имеет специальное имя
<init>
.
Итак, JVM инициализирует класс или метод инициализации интерфейса, а не метод инициализации экземпляра , который на самом деле является конструктором. Поэтому им не нужно упоминать, что основной метод должен быть статическим в спецификации JVM, поскольку он подразумевается тем фактом, что экземпляр не создается до вызова основного метода.
Недавно аналогичный вопрос был опубликован на Programmers.SE
Ищете окончательный ответ от первичного или вторичного источника, почему (в частности) Java и С# решили использовать статический метод в качестве точки входа, а не представлять экземпляр приложения экземпляром класса
Application
с точкой входа, являющейся подходящим конструктором?
TL;DR часть принятого ответа:
В Java причина
public static void main(String[] args)
заключается в том, что
- Gosling хотел
- код, написанный кем-то, имеющим опыт работы на C (не на Java)
- для выполнения кем-либо, используемым для запуска PostScript на NeWS
Для С# рассуждения транзитно похожи, так сказать. Дизайнеры языка сохранили > Для входа в программу, знакомое программистам из Java. Как архитектор С# Андерс Хейлсберг ставит его,... наш подход с С# просто заключался в том, чтобы предложить альтернативу... Java-программистам...
...
Это просто конвенция. JVM, безусловно, может иметь дело с нестационарными основными методами, если бы это было соглашение. В конце концов, вы можете определить статический инициализатор в своем классе и создать экземпляр объекта zillion до того, как вы когда-либо дойдете до своего метода main().
Ключевое слово public
- это модификатор доступа, который позволяет программисту контролировать
видимость членов класса. Когда член класса предшествует public
, то это
член может получить доступ к коду вне класса, в котором он объявлен.
Противоположностью public
является private
, что предотвращает использование члена из кода, определенного вне его класса.
В этом случае main()
должен быть объявлен как public
, так как он должен быть вызван
по коду вне его класса при запуске программы.
Ключевое слово static
позволяет
main()
для вызова без необходимости экземпляра конкретного экземпляра класса. Это необходимо, так как main()
вызывается интерпретатором Java до того, как будут созданы какие-либо объекты.
Ключевое слово void
просто сообщает компилятору, что main()
не возвращает значение.
Истинная точка входа в любое приложение является статическим методом. Если язык Java поддерживал метод экземпляра как "точку входа", тогда среда выполнения должна была внедрить ее внутренне как статический метод, который построил экземпляр объекта с последующим вызовом метода экземпляра.
С этой точки зрения я рассмотрю обоснование выбора одного из следующих трех вариантов:
static void main()
, как мы видим сегодня.void main()
вызывает только что созданный объект.Program
, то выполнение будет состоять из new Program()
). static void main()
main()
. void main()
new ClassName()
.main()
. new ClassName()
Я пойду в обратном порядке для этого.
Имейте в виду, что одной из целей дизайна Java было подчеркнуть (потребовать, когда это возможно) хорошие методы объектно-ориентированного программирования. В этом контексте конструктор объекта инициализирует объект, но не должен нести ответственность за поведение объекта. Поэтому спецификация, которая дала точку входа new ClassName()
, путала бы ситуацию для новых разработчиков Java, заставляя исключение создавать конструктор "идеальный" для каждого приложения.
Сделав main()
метод экземпляра, эта проблема, безусловно, будет решена. Тем не менее, он создает сложность, требуя, чтобы спецификация отображала подпись конструктора класса входа, а также подпись метода main()
.
Таким образом, с указанием static void main()
создает спецификацию с наименьшей сложностью, придерживаясь принципа размещения поведения в методах. Учитывая, насколько просто реализовать метод main()
, который сам создает экземпляр класса и вызывает метод экземпляра, нет реального преимущества для указания main()
как метода экземпляра.
Я не знаю, вызвал ли JVM основной метод перед созданием объектов... Но есть гораздо более веская причина, по которой метод main() статичен... Когда JVM вызывает основной метод класса ( скажем, Person)... он вызывает его " Person.main()". Видите ли, JVM вызывает его по имени класса. Вот почему метод main() должен быть статическим и общедоступным, поэтому он может быть доступен JVM.
Надеюсь, это помогло...:)... Если бы это было так, дайте мне знать, комментируя..!: D
static - Когда JVM делает вызов основного метода, для вызываемого класса нет объекта, поэтому он должен иметь статический метод, чтобы разрешить вызов из класса.
Статические методы не требуют какого-либо объекта. Он запускается напрямую, так что основные запускаются напрямую.
Статическое ключевое слово в основном методе используется, потому что в основном методе нет никакого экземпляра. Но объект построен, а не вызов, в результате мы используем статическое ключевое слово в основном методе. В jvm контексте память создается, когда класс загружается в нее. И все статические члены присутствуют в этой памяти. если мы сейчас сделаем основной статический файл, он будет в памяти и будет доступен для jvm (class.main(..)), поэтому мы можем вызвать основной метод с необходимостью создания даже необходимости создания кучи.
Это просто соглашение, как мы можем видеть здесь:
Метод должен быть объявлен открытым и статическим, он не должен возвращать значение, и он должен принять массив String в качестве параметра. По умолчанию, первый необязательный аргумент - это имя вызываемого класса. Должно использоваться полное имя класса. Если параметр -jar указанный, первый аргумент без аргумента - это имя архива JAR содержащих класс и файлы ресурсов для приложения, с класс запуска, обозначенный заголовком манифеста Main-Class.
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html#description
Открытые ключевые слова static void означают, что интерпретатор виртуальной машины Java (JVM) может вызывать основной метод программы для запуска программы (общедоступный) без создания экземпляра класса (статического), и программа не возвращает данные в Java VM interpreter (void), когда он заканчивается.
Любой метод, объявленный как static в Java, принадлежит самому классу.
Снова статический метод конкретного класса может быть доступен только путем обращения к классу типа Class_name.method_name();
Поэтому для доступа к статическому методу не нужно создавать экземпляр класса.
Таким образом, метод main() объявляется как static
, так что к нему можно получить доступ без создания объекта этого класса.
Так как мы сохраняем программу с именем класса, где присутствует основной метод (или из которого программа должна начать выполнение, применима для классов без метода main()
(Расширенный уровень)). Таким образом, вышеупомянутым способом:
Class_name.method_name();
доступен основной метод.
Вкратце, когда программа скомпилирована, она ищет метод main()
, имеющий String
аргументы, такие как: main(String args[])
в указанном классе (то есть по имени программы), и поскольку в начале он имеет нет возможности для создания экземпляра этого класса, поэтому метод main() объявляется как статический.
В основном мы делаем эти ЧЛЕНЫ ДАННЫХ и ФУНКЦИИ ЧЛЕНОВ как STATIC, которые не выполняют никаких задач, связанных с объектом. И в случае основного метода мы делаем его как STATIC, потому что он не имеет ничего общего с объектом, поскольку основной метод всегда запускается независимо от того, создаем ли мы объект или нет.
есть простая причина, потому что объект не требуется для вызова статического метода, если он был нестационарным методом, Java-виртуальная машина сначала создает объект, а затем вызывает метод main(), который приведет к проблеме дополнительных выделение памяти.