Подтвердить что ты не робот

Почему спецификации Java требуют, чтобы основной метод программы был недействительным?

Хотя тип возврата не является частью сигнатуры метода, JVM ищет точное объявление как

 public static void main(String[] args)

Мое предположение заключается в том, что поскольку в сигнатуре метода нет включенного типа возврата, я должен быть разрешено изменять тип возврата.

Но если я изменил его на public static int main(String[] args) и вернул значение, скажем 0, JVM не сможет выполнить программу и выходит с ошибкой

Error: Main method must return a value of type void in class TestData, please 
define the main method as:
   public static void main(String[] args)

Почему спецификации Java требуют, чтобы основной метод был недействительным? Почему это ограничение, когда тип возврата не является частью сигнатуры метода?

Этот вопрос отличается от Почему main() в java void?: этот вопрос закрыт, поскольку он основан на мнениях, в то время как я ищу места кода/процессы, из которых JVM вызывает этот метод, и каковы ограничения, которые вынуждают их поддерживать этот метод как недействительный. Каковы принятые ими проектные решения (и аргументы позади), и где это задокументировано.

Я ищу факты, чтобы узнать причину, почему это так. Пожалуйста, не помещайте его в дубликат, не просматривая детали вопроса.

PS: выход, это еще одна вещь. Меня больше беспокоит вход в программу. Кроме того, возвращаемое значение может быть не связано с использованием JVM, ограничивая его расширением допустимых пределов.

До сих пор я узнал из этого вопроса: спецификации Java имеют явно установленный тип возвращаемого значения, чтобы избежать путаницы с мигрирующими программистами (C/CPP), которые могут ожидать, что это значение вернется к ОС, но поскольку JVM находится между ними значение никогда не будет возвращено ОС. Для этого специального назначения (возвращаемого значения для ОС) они предоставили метод System.exit().


Для всех тех, кто предлагает, чтобы возвращаемый тип был частью сигнатуры. Просто попробуйте определить оба следующих метода в классе

    public static void main(String[] a){

    }
    public static String main(String[] a){

    }

Вы получите ошибку компиляции, потому что подпись обоих этих методов одинакова.

4b9b3361

Ответ 1

main is void указан в JLS 12.1.4 Invoke Test.main:

Метод main должен быть объявлен public, static и void.

Иногда ответ на вопрос почему? потому что спецификация говорит так (например, Quod Ego Dixit, или потому что я говорю так (Терри Пратчетт)). Иногда решения дизайнера языка недоступны, и единственное, что мы можем сделать, это догадываться. Это также является причиной того, что очевидный дубликат (Почему main() в java void?) закрывается, в основном, на основе мнения.

Теперь, как для меня - очевидная причина: JLS 12.8 Выход программы говорит:

Программа завершает всю свою деятельность и выходит, когда происходит одна из двух вещей:

  • Все потоки, которые не являются потоками демона, завершаются.
  • Некоторый поток вызывает метод exit класса Runtime или class System, а операция выхода не запрещена менеджером безопасности.

Это означает, что конец метода main не обязательно означает конец программы. Код возврата из метода main имеет хорошо известный смысл в таких языках, как C: это код выхода процесса. Это значение не применяется, если метод main может выйти задолго до завершения самого процесса.

Большинство нетривиальных приложений Java имеют - обычно - недолговечный основной метод, который запускает один или несколько долгоживущих не-демона. Разрешение кода возврата из метода Java main может означать смысл, который на самом деле отсутствует: возвращаемое значение - это код выхода процесса. Таким образом, явным образом указываю, что main должен иметь тип возврата void - это хорошо: он уменьшает путаницу или присваивает значение, которого нет.

Ответ 2

Основной метод может не быть точкой выхода в конце концов. Из-за многопоточности может случиться так, что при возврате основного объекта на поле появляется еще один поток, поддерживающий программу. В этом случае код выхода не имеет смысла.

Ответ 3

Почему не пусто?

Если вы хотите вернуть некоторый статус в ОС, вы можете использовать любой из существующих методов. Самый общий из них - System.exit(int status).

Если ваша основная часть заканчивается перед другими потоками, возвращаемое значение не имеет значения. Это контрастирует с c/С++, который не поддерживает многопоточность этого времени.

Как и приложение для качания, возможно, по-прежнему работают на EDT после завершения основного.

И если вы все еще рассматриваете точку входа, но возвращаемый тип всегда говорит о выходе.

Таким образом, он просто недействителен, поскольку у нас есть сигнализаторы статуса для возврата значения или возврата в другом случае. Тем не менее, нет другого смысла, потому что он был разработан таким образом. Другой разработчик с разными мыслями может бросить другую идею для решения той же ситуации.

Ответ 4

Как указано в http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.8

12,8. Выход программы

Программа завершает всю свою деятельность и выходит, когда одна из двух вещей бывает:

Все потоки, которые не являются потоками демона, завершаются.

В некотором потоке вызывается метод exit класса Runtime или класс System, и диспетчер безопасности не запрещает операцию выхода.

программа выходит, если все запущенные потоки деамоны. Поэтому, если у вас есть поток non deamon, основной метод может вернуться до завершения программы.

Время жизни вашей программы может продлить время жизни основного метода, а номер возврата может быть определен позже в программе.

Я думаю, именно поэтому они используют System.exit() в качестве точки возврата.

Ответ 5

Вы не можете смотреть ниже из Java Docs, так как ваш основной метод служит точкой выхода, вам нужно, чтобы метод был недействительным. или у вас есть возможность вызывать system.exit() явно в конце вашего основного.

Завершает работу запущенной виртуальной машины Java. Аргумент служит в качестве кода состояния; по соглашению, ненулевой код состояния указывает на ненормальное завершение.

Ответ 6

Как мне известно,

Причиной метода main, имеющего void в качестве возвращаемого типа, является то, что, как только метод main завершит его выполнение, это не означает, что вся программа завершена. У него могут быть потоки, инициированные и запущенные за сценой. Даже если основной поток мертв, все же есть шанс, что потоки дочерних потоков будут запущены. В этом случае тип возврата main не имеет большого смысла.

И JVM будет контролировать статус завершения программы, чтобы освободить память, Не нужно возвращать что-то в JVM, в котором говорится, что программа завершена. На C-языке мы напрямую общаемся с O.S. поэтому есть возможность вернуть значение int O.S. в котором говорится, что выполнение выполнено и начало освобождения памяти. Но здесь, в java, JVM будет общаться с O.S. но не программа, поэтому нам не нужно ничего возвращать из основного.

Надеюсь, это очистит ваши сомнения.

Ответ 7

Если вы спросите JVM о запуске класса, java runtime будет искать именно эту подпись в вашем классе public static void main(String[] args) Это ваш контракт с JVM, если нет, он не будет выполняться. Если вы хотите вернуть код int, используйте System.exit

Ответ 8

Консольная программа возвращает код возврата int, и, таким образом, в традиционной программе на языке C int main(int argc, char** argv) кажется логичным.

В Java был добавлен исключение как новый механизм потока управления, а также смоделирован или реализован также многопоточность. Выход можно было сделать везде с помощью System.exit(int returnCode).

Это означает, что вызов main вложен в кусок кода, а самый чистый (минималистический, меньше случаев, без магии return 0) - по умолчанию для возврата 0, за исключением System.exit.

Разум, java был нацелен на то, чтобы сильно "улучшить" C и особенно С++. Как и Strings и char, которые используют полный Unicode, а не байт.

Ответ 9

Java был разработан как Platform independent language. Поэтому, если метод main() возвращает значение (например, 0 или 1 или что-то еще), его можно интерпретировать или понимать по-разному на другой платформе. Таким образом, в отличие от C и Cpp метод main() не может вернуть значение.

Ответ 10

Основная причина заключается в том, что в случаях общего использования, особенно в многопотоковых и графических приложениях, вы не предпочитаете иметь возвращаемое значение в основном. Но если у вас есть такой вариант использования, вы можете использовать метод выхода. Именно по этой причине вы ищите.

Ответ 11

Что такое основной метод в Java?

Основной метод в Java - это точка входа для любой основной Java-программы. Помните, что мы не говорим о Servlet, MIDlet или любой другой управляемой контейнером Java-программе, где предусмотрены методы жизненного цикла для управления выполнением. В основной программе Java выполнение начинается с основного метода при вводе имени основного класса java, Поиск JVM для общедоступного static void main (String args []) метода в этом классе и , если он не находит этот метод, он выдает ошибку NoSuchMethodError: main и завершает.

Подпись основного метода в Java

Основной метод должен строго следовать его синтаксису; другой мудрый JVM не сможет найти его, и ваша программа не будет работать. Вот точная подпись основного метода:

public static void main (String args [])

Эта подпись является классической сигнатурой и там с начала Java, но с введением переменного аргумента или varargs в Java5 вы также можете объявить основной метод в Java с использованием синтаксиса varargs, как показано ниже:

public static void main (String... args)

Помните, что varargs версия основного метода java будет работать только в Java 1.5 или более поздней версии. Помимо публичных, статических и недействительных есть определенные ключевые слова, такие как final, synchronized и strictfp, которые разрешены в сигнатуре основного метода java.

Почему основной метод статичен в Java

почему главный метод - public static void в JavaNow, приходят к основному вопросу "Почему главный метод статичен в Java", существует немало причин, но здесь есть несколько причин, которые имеют для меня смысл:

  • Поскольку основным методом является статическая виртуальная машина Java, она может вызывать ее без создания какого-либо экземпляра класса, который содержит основной метод.

  • Так как C и С++ также имеют аналогичный основной метод, который служит точкой входа для выполнения программы, то это соглашение будет помогать Java.

  • Если основной метод не был объявлен статическим, а JVM должен создать экземпляр основного класса, и поскольку конструктор может быть перегружен и может иметь аргументы, для JVM не будет определенного и последовательного способа найти основной метод в Java.

  • Все, что объявлено в классе в Java, относится к эталонному типу и требует, чтобы объект был создан до их использования, но статический метод и статические данные загружаются в отдельную память внутри JVM, называемую контекстом, который создается при загрузке класса, Если основной метод статический, он будет загружен в контексте JVM и доступен для выполнения.

Почему main mehtod является общедоступным в Java

Java указывает несколько модификаторов доступа, например. частной, защищенной и публичной. Любой метод или переменная, объявленная публикой в ​​Java, может быть доступна извне этого класса. Поскольку основной метод Java, JVM может легко получить доступ и выполнить его.

Почему основной метод недействителен в Java

Поскольку основной метод в Java не должен возвращать какое-либо значение, его сделанная пустота, которая просто означает, что main ничего не возвращает.

Резюме:

  • Основной метод должен быть объявлен открытым, статическим и void в Java, иначе JVM не сможет запускать программу Java.

  • JVM выбрасывает NoSuchMethodException: главное, если он не находит основной метод предопределенной подписи в классе, который предоставляется команде Java. Например. если вы запустите java Helloworld, а JVM будет искать общедоступный статический void main String args []) метод в файле HelloWorld.class.

  • Основной метод - это точка входа для любой программы Core Java. Выполнение начинается с основного метода.

4. Основной метод запускается специальным потоком, называемым "основным" потоком в Java. Ваша Java-программа будет работать до тех пор, пока ваш основной поток не будет запущен или не будет создан нить, отличная от daemon от основного метода.

  1. Когда вы видите "Исключение в главной теме", например. Исключение в главной теме: Java.lang.NullPointerException означает, что исключение выбрасывается внутри основного потока.

  2. Вы можете объявить основной метод, используя синтаксис varargs, начиная с Java 1.5, например. public static void main (String... args)

  3. Помимо статического, void и public вы можете использовать final, synchronized и strictfp модификатор в сигнатуре основного метода в Java.

  1. Основной метод в Java может быть перегружен, как и любой другой метод в Java, но JVM будет вызывать только основной метод с указанной указанной сигнатурой выше.
  1. Вы можете использовать предложение throws в сигнатуре основного метода и можете выкинуть любое отмеченное или непроверенное исключение.

  2. Статический блок инициализатора выполняется еще до того, как JVM вызывает основной метод. Они выполняются, когда класс загружается в память JVM.

Надеюсь, это ответит на ваш вопрос об основном методе:)

Обновить в ответ на:

Одна небольшая проблема с вашим ответом: тип возврата не является частью подпись метода. Следовательно, JVM не должен генерировать исключение "NoSuchMethodException: main", если тип возврата отличается.

он не возвращает "NoSuchMethodException: main", если тип возврата отличается, а тип возврата является частью сигнатуры метода. Взгляните на этот снимок экрана:

введите описание изображения здесь

Ответ 12

Мы можем сказать, что main метод как метод инициализации класса, так как он удовлетворяет одному из критериев инициализации класса; Пожалуйста, обратитесь http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4, 12.4.1 раздел -

T - класс, и статический метод, объявленный T, вызывается.

Теперь, согласно спецификации JVM, команда return используется для возврата из методов, объявленных как void, методов инициализации экземпляра, и методов инициализации класса или интерфейса. http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.11.8

Подробнее о команде возврата см. здесь: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.1.9.return