Je cherche une réponse définitive d'une source primaire ou secondaire expliquant pourquoi (notamment) Java et C # ont décidé de choisir une méthode statique comme point d'entrée, plutôt que de représenter une instance d'application par une instance d'une Application
classe (avec le point d'entrée être un constructeur approprié).
Contexte et détails de mes recherches antérieures
Cela a été demandé auparavant. Malheureusement, les réponses existantes ne font que poser la question . En particulier, les réponses suivantes ne me satisfont pas, car je les juge incorrectes:
- Il y aurait une ambiguïté si le constructeur était surchargé. - En fait, C # (ainsi que C et C ++) autorise différentes signatures, de
Main
sorte que la même ambiguïté existe et est traitée. - Une
static
méthode signifie qu'aucun objet ne peut être instancié avant que l'ordre d'initialisation soit clair. - Ceci est faux, certains objets sont instanciés avant (par exemple dans un constructeur statique). - Ils peuvent donc être appelés par le runtime sans avoir à instancier un objet parent. - Ce n'est pas une réponse du tout.
Juste pour justifier davantage pourquoi je pense que cette question est valable et intéressante:
De nombreux cadres font utiliser des classes pour représenter les applications et les constructeurs comme points d'entrée. Par exemple, l' infrastructure d'application VB.NET utilise un dialogue principal dédié (et son constructeur) comme point d'entrée 1 .
Ni Java ni C # n’ont techniquement besoin d’ une méthode principale. Eh bien, C # a besoin d’être compilé, mais pas même Java. Et dans aucun cas, il est nécessaire pour l'exécution. Cela ne semble donc pas être une restriction technique. Et, comme je l'ai mentionné dans le premier paragraphe, une simple convention semble étrangement incompatible avec le principe de conception général de Java et de C #.
Pour être clair, il n’ya pas d’ inconvénient particulier à avoir une main
méthode statique , c’est tout simplement étrange , ce qui m’a amené à me demander s’il existait une justification technique.
Je suis intéressé par une réponse définitive d'une source primaire ou secondaire, pas de simples spéculations.
1 Bien qu'il existe un callback ( Startup
) qui peut l'intercepter.
la source
Réponses:
TL; DR
En Java, la raison
public static void main(String[] args)
est quePour C #, le raisonnement est transitoirement similaire pour ainsi dire. Les concepteurs de langage ont gardé la syntaxe de point d’entrée de programme familière pour les programmeurs venant de Java. Comme le dit l’architecte C #, Anders Hejlsberg ,
Version longue
expansion au-dessus et soutenu avec des références ennuyeuses.
java Terminator Hasta la vista bébé!
VM Spec, 2.17.1 Démarrage de la machine virtuelle
... voir aussi: Annexe: J'ai besoin de tes vêtements, de tes bottes et de ta moto
exécution ciblée pour une utilisation similaire aux scripts classiques dans l'interface de ligne de commande.
marche de côté importante
... cela permet d'éviter quelques fausses traces dans notre enquête.
VM Spec, 1.2 La machine virtuelle Java
J'ai remarqué ci-dessus lors de l'étude du chapitre précédent - 1.1 Histoire qui, selon moi, pourrait être utile (mais s'est avérée inutile).
exécution est régie par la seule spécification de machine virtuelle, qui
déclare explicitement qu'elle n'a rien à voir avec le langage Java
=> OK pour ignorer JLS et tout élément lié au langage Java.
Gosling: un compromis entre C et langage de script ...
Sur la base de ce qui précède, j'ai commencé à rechercher sur le Web l' historique de la JVM . N'a pas aidé, trop de déchets dans les résultats.
Ensuite, je me suis rappelé les légendes sur Gosling et ma recherche a été réduite à l’ histoire de Gosling JVM .
Eureka! Comment les spécifications de la JVM sont devenues
déclaration explicite qu’au moment de la création,
C et le script ont été considérés comme les influences les plus importantes.
Déjà vu clin d' œil à des scripts dans VM Spec 2.17.1, les
arguments de ligne de commande expliquent suffisamment ,
String[] args
mais
static
etmain
ne sont pas encore là, le besoin de creuser plus loin ...Notez que lorsque vous tapez ceci - connexion de C, de script et de VM Spec 1.2 avec sa technologie rien de Java - je me sens comme quelque chose de familier, quelque chose ... orienté objet est en train de disparaître lentement. Prends ma main et continue à avancer Ne ralentis pas, nous y sommes presque
Les diapositives Keynote sont disponibles en ligne: 20_Gosling_keynote.pdf , ce qui est très pratique pour copier des points clés.
A-ha! Regardons de plus près la syntaxe C .
Est-ce qu'on se rapproche? tu paries. Il est également intéressant de suivre le lien "principal" de la citation ci-dessus:
pour que le développeur C soit à l'aise, le point d'entrée du programme doit être
main
.De plus, comme Java requiert que toute méthode soit dans la classe, elle
Class.main
estaussi proche que possible: invocation statique, juste nom de classe et point,
pas de constructeur s'il vous plaît - C ne sait rien de tel.
Ceci s’applique également de manière transitoire au C #, en tenant compte de
l’idée d’une migration aisée de ce dernier vers Java.
Les lecteurs qui pensent que le point d’entrée du programme est sans importance sont invités à rechercher et à vérifier les questions de Stack Overflow dans lesquelles des personnes de Java SE essaient d’écrire Hello World pour Java ME MIDP. Remarque Le point d’entrée MIDP n’a pas de
main
nistatic
.Conclusion
Sur la base de ce qui précède, je dirais que
static
,main
et queString[] args
c’était au moment de la création de Java et de C # le choix le plus raisonnable pour définir le point d’entrée du programme .Annexe: J'ai besoin de tes vêtements, de tes bottes et de ta moto
Je dois admettre que la lecture de VM Spec 2.17.1 était très amusant.
Références symboliques de
Terminator
oh ouais.la source
Cela me semble vaguement abusif. Un constructeur est utilisé pour l'initialisation d'un objet: il configure un objet, qui est ensuite utilisé par le code qui l'a créé.
Si vous insérez des fonctionnalités d'utilisation de base dans le constructeur et n'utilisez jamais l'objet créé par le constructeur dans le code externe, vous enfreignez les principes de la POO. Fondamentalement, faire quelque chose de vraiment bizarre sans raison apparente.
Pourquoi voudriez-vous faire ça quand même?
la source
Main
méthode fonctionne bien pour le cas simple, et n'est pas vraiment un problème dans les cas les plus difficiles, alors pourquoi pas?Pour Java, je penserais que le raisonnement est simple: lors du développement de Java, les développeurs savaient que la plupart des personnes apprenant le langage maîtriseraient le C / C ++ auparavant.
Ainsi, non seulement Java ressemble beaucoup à C / C ++ au lieu de dire smalltalk, mais il a également repris les idiosynchronisations de C / C ++ (il suffit de penser aux littéraux entiers octaux). Comme c / c ++ utilisent tous deux une méthode principale, il était logique de procéder de la même manière pour Java de ce point de vue.
Je suis sûr que je me souviens de bloch ou de quelqu'un qui a dit quelque chose dans ce sens à propos de la raison pour laquelle ils ont ajouté des littéraux octaux entiers, je vais voir si je peux trouver des sources :)
la source
:
enextends
? Et à l'public static void main(String [ ] args)
intérieur d'une classe, c'est très différent de l'int main(int argc, char **argv)
extérieur.:
pourextends
est une question de syntaxe et sont essentiellement les mêmes. Tout le reste est dicté par la langue.main()
, alors qu’il n’était apparemment pas assez important dans d’autres cas.Eh bien, il existe de nombreuses fonctions principales qui exécutent une boucle infinie. Un constructeur qui travaille de cette façon (avec un objet qui ne se construit jamais) est ce qui me semble étrange.
Il y a tellement de choses amusantes à propos de ce concept. Votre logique s'exécute sur un objet à naître, des objets nés pour mourir (puisqu'ils font tout leur travail dans le constructeur), ...
Tous ces effets secondaires ne vont-ils pas corrompre beaucoup plus le wagon OO qu'un simple public (parce qu'il doit être accédé par un inconnu) statique (car aucune instance n'est nécessaire pour que nous puissions commencer) void main (parce que c'est le point d'entrée )?
Pour qu'un point d'entrée simple, simple et fonctionnel, existe en Java, il faut automatiquement public et static. Bien qu’il s’agisse d’une méthode statique , elle se résume à ce que nous pouvons obtenir de plus près d’une fonction simple pour accomplir ce que nous souhaitons: un simple point d’entrée.
Si vous n'allez pas adopter un point d'entrée simple, clair et fonctionnel, comme point d'entrée. Quelle est la suite qui ne semble pas étrange en tant que constructeur que ce n'est pas destiné à construire?
la source
Vous pouvez rapidement exécuter des tests autonomes sur une classe, pendant le développement, en collant un
main()
dans la classe que vous essayez de tester.la source
Vous devez commencer quelque part. Un environnement statique principal est l’environnement d’exécution le plus simple qui soit. Aucune instance n’est nécessaire (en dehors de la JVM et des paramètres de chaîne simples) ne doit être créée. Elle peut donc "apparaître" avec un minimum de tracas (et une faible probabilité d'une erreur de codage empêchant le démarrage, etc.) et permet de faire des choses simples sans beaucoup d'autres configurations.
Fondamentalement une application de KISS.
[Et, bien sûr, la raison principale est: pourquoi pas?]
la source
À ma connaissance, la raison principale est simple. Sun était une société Unix vendant des machines Unix et Unix est l’objet de la convention C "principale (args)" pour invoquer un binaire .
De plus, Java a été explicitement conçu pour être facilement lisible par les programmeurs C et C ++. Il n’y avait donc aucune bonne raison de ne pas simplement se contenter de la convention C.
L'approche choisie, dans laquelle chaque classe peut avoir une méthode d'appel, est assez flexible, en particulier en combinaison avec la
Main-Class
ligne du fichier MANIFEST.MF dans un fichier jar exécutable.la source
Selon la philosophie de la programmation orientée objet, un programme ne serait pas un objet du point de vue du processus de système d’exploitation, car il n’était pas possible d’en avoir plus d’un par définition.
De plus, un constructeur n'est en aucun cas un point d'entrée.
Il me semble que le choix le plus raisonnable est d’avoir main comme fonction statique, ce qu’il est en réalité à la fin de la journée. Compte tenu de l’architecture de machines virtuelles telles que JVM et CLR, tout autre choix le pousserait inutilement.
la source
Runnable
objets à plusieurs threads.