Я ищу точный ответ из первичного или вторичного источника, почему (в частности) Java и C # решили использовать статический метод в качестве своей точки входа, а не представлять экземпляр приложения экземпляром Application
класса (с точкой входа быть подходящим конструктором).
Предпосылки и детали моего предыдущего исследования
Об этом уже спрашивали. К сожалению, существующие ответы просто напрашиваются на вопрос . В частности, следующие ответы меня не удовлетворяют, так как я считаю их неверными:
- Не было бы двусмысленности, если бы конструктор был перегружен. - На самом деле, C # (а также C и C ++) допускают разные сигнатуры,
Main
поэтому существует и существует одна и та же потенциальная неоднозначность. static
Метод означает объекты не могут быть созданы таким образом , прежде чем порядок инициализации ясен. - Это просто фактически неверно, некоторые объекты являются экземплярами ранее (например , в статическом конструкторе).- Таким образом, они могут быть вызваны средой выполнения без необходимости создания экземпляра родительского объекта. - Это не ответ вообще.
Просто чтобы объяснить, почему я считаю этот вопрос актуальным и интересным:
Многие структуры делают использовать классы для представления приложений и конструкторов в качестве точек входа. Например, прикладная среда VB.NET использует выделенный главный диалог (и его конструктор) в качестве точки входа 1 .
Ни Java, ни C # технически не нуждаются в основном методе. Ну, C # нужен для компиляции, но Java даже не это. И ни в том, ни в другом случае это не нужно для исполнения. Так что это не является техническим ограничением. И, как я уже упоминал в первом абзаце, для простого соглашения это кажется странно несовместимым с общим принципом разработки Java и C #.
Чтобы быть ясным, нет никакого особенного недостатка в наличии статического main
метода, это просто явно странно , что заставило меня задуматься, есть ли какое-то техническое обоснование этого.
Я заинтересован в окончательном ответе из первичного или вторичного источника, а не просто в предположениях.
1 Хотя есть обратный вызов ( Startup
), который может перехватить это.
источник
Ответы:
TL; DR
В Java причина в
public static void main(String[] args)
том, чтоДля C # рассуждения транзитивно похожи, так сказать. Разработчики языка сохранили синтаксис точки входа в программу знакомым для программистов из Java. Как говорит C # архитектор Андерс Хейлсберг ,
Длинная версия
расширение выше и подкреплено скучными ссылками.
Java Терминатор Хаста ла Виста Детка!
VM Spec, 2.17.1 Запуск виртуальной машины
... см. также: Приложение: мне нужна твоя одежда, твои ботинки и твой мотоцикл
выполнение предназначено для использования как типичные сценарии в интерфейсе командной строки.
важный шаг
... это помогает избежать нескольких ложных следов в нашем расследовании.
VM Spec, 1.2 Виртуальная машина Java
Я заметил выше, когда изучал предыдущую главу - 1.1 История, которая, на мой взгляд, могла бы быть полезной (но оказалась бесполезной).
выполнение регулируется только спецификацией VM, которая
явно заявляет, что она не имеет ничего общего с языком Java
=> OK, чтобы игнорировать JLS и все, что связано с языком Java.
Гослинг: компромисс между Си и языком сценариев ...
Исходя из вышеизложенного, я начал искать в Интернете историю JVM . Не помогло, слишком много мусора в результатах.
Затем я вспомнил легенды о Гослинге и сузил свой поиск до истории Гослинг-JVM .
Эврика! Как появилась спецификация JVM
явное заявление о том, что в момент создания
C и сценарии считались наиболее важными факторами.
Уже видели кивок к скриптинг в VM Spec 2.17.1,
аргументы командной строки , достаточно объяснить ,
String[] args
но
static
иmain
еще не там, нужно копать дальше ...Обратите внимание, что при наборе этого слова - соединяя C, скрипты и VM Spec 1.2 с его ничего-Java-я - я чувствую себя как что-то знакомое, что-то ... объектно-ориентированное медленно исчезает. Возьми меня за руку и продолжай двигаться.
Слайды Keynote доступны онлайн: 20_Gosling_keynote.pdf , довольно удобно для копирования ключевых моментов.
Ага! Давайте подробнее рассмотрим синтаксис Си .
Мы приближаемся? Вы держите пари Также стоит перейти по «главной» ссылке сверху цитаты:
чтобы быть удобным для разработчика на C, должна быть точка входа в программу
main
.Кроме того, поскольку Java требует, чтобы любой метод был в классе,
Class.main
оннастолько близок, насколько это возможно: статический вызов, просто имя класса и точка,
пожалуйста , никаких конструкторов - C ничего такого не знает.
Это также транзитивно относится к C #, принимая во внимание
идею легкого перехода на него с Java.
Читатели, считающие, что знакомая точка входа в программу не имеет значения, приглашаются на поиск и проверку вопросов переполнения стека, где ребята из Java SE пытаются написать Hello World для Java ME MIDP. Примечание. Точка входа MIDP не имеет
main
ниstatic
.Заключение
На основании выше , я бы сказал , что
static
,main
иString[] args
были в моменты Java и C # создание наиболее разумных решений по определению программы точки входа .Приложение: мне нужна твоя одежда, твои ботинки и твой мотоцикл
Должен признаться, чтение VM Spec 2.17.1 было огромным удовольствием.
Символические ссылки от
Terminator
ах да.источник
Это просто кажется мне оскорбительным. Конструктор используется для инициализации объекта: он устанавливает объект, который затем используется кодом, который его создал.
Если вы помещаете базовые функциональные возможности использования в конструктор, а затем никогда не используете объект, который конструктор создает во внешнем коде, то вы нарушаете принципы ООП. По сути, делать что-то действительно странное без видимой причины.
Зачем тебе это делать?
источник
Main
метода хорошо работает в простом случае и не является проблемой в более сложных случаях, так почему бы и нет?Что касается Java, я думаю, что причина проста: при разработке Java разработчики знали, что большинство людей, изучающих язык, будут знать C / C ++ заранее.
Следовательно, Java не только во многом похожа на C / C ++, а не на smalltalk, но и переняла отличительные черты от C / C ++ (просто подумайте о восьмеричных целочисленных литералах). Поскольку c / c ++ оба используют основной метод, то же самое для java имеет смысл с этой точки зрения.
Я почти уверен, что помню, как Блох или кто-то говорил что-то вроде этого о том, почему они добавили восьмеричные целочисленные литералы, я посмотрю, смогу ли я найти некоторые источники :)
источник
:
наextends
? Иpublic static void main(String [ ] args)
внутри класса это совсем не то, чтоint main(int argc, char **argv)
вне класса.:
наextends
это вопрос синтаксиса и по сути то же самое. Все остальное продиктовано языком.main()
, когда, очевидно, это было недостаточно важно в других случаях.Ну, есть много основных функций, которые просто запускают бесконечный цикл. Конструктор, работающий таким образом (с объектом, который никогда не создается) - это то, что мне кажется странным.
В этой концепции так много забавных вещей. Ваша логика работает поверх нерожденного объекта, объектов, которые рождены, чтобы умереть (поскольку они делают всю свою работу в конструкторе), ...
Разве все эти побочные эффекты не повредят OO wagon намного больше, чем простой общедоступный (потому что к нему должен получить доступ неизвестный) static (потому что нам не нужен экземпляр, чтобы начать работу) void main (потому что это точка входа )?
Для простой, простой, точки входа в функцию, существующей в Java, автоматически требуются public и static. Хотя это статический метод , он сводится к тому, что мы можем приблизить к простой функции для достижения желаемого: простой точке входа.
Если вы не собираетесь использовать простую, простую, функциональную точку входа в качестве точки входа. Что дальше, что не кажется странным как конструктор, который не предназначен для построения?
источник
Вы можете быстро запустить некоторые автономные тесты для класса во время разработки, вставив
main()
в класс, который вы пытаетесь протестировать.источник
Вы должны начать где-нибудь. Статическое main - это простейшая среда выполнения, которую вы можете иметь - не нужно создавать ни одного экземпляра (вне JVM и простых строковых параметров), поэтому он может «придумать» минимум суеты (и малую вероятность) ошибки кодирования, препятствующей запуску и т. д.), и может делать простые вещи без множества других настроек.
В основном приложение KISS.
[И, конечно же, главная причина: почему бы и нет?]
источник
Насколько я понимаю, основная причина проста. Sun была Unix-компанией, продающей Unix-машины, и Unix - это то, для чего было разработано соглашение C "main (args)" для вызова двоичного файла.
Кроме того, Java была явно разработана так, чтобы ее было легко подобрать для программистов на C и C ++, поэтому не было веских оснований для того, чтобы просто не использовать соглашение C.
Выбранный подход, при котором каждый класс может иметь метод вызова, достаточно гибок, особенно в сочетании со
Main-Class
строкой в файле MANIFEST.MF в исполняемом фляге.источник
Это не согласуется с философией ООП, согласно которой программа была бы объектом с точки зрения процесса ОС, поскольку не существует способа иметь более одного по определению.
Кроме того, конструктор никоим образом не является точкой входа.
Мне кажется, что самый разумный выбор - использовать main как статическую функцию, какой она на самом деле является в конце дня. Учитывая архитектуру виртуальных машин, таких как JVM и CLR, любой другой выбор был бы излишним.
источник
Runnable
объектов с несколькими потоками.