La signature de méthode d'une méthode Javamain ()est la suivante:
public static void main(String[] args){
...
}
Y a-t-il une raison pour que cette méthode soit statique?
La méthode est statique car sinon il y aurait une ambiguïté: quel constructeur devrait être appelé? Surtout si votre classe ressemble à ceci:
public class JavaClass{
protected JavaClass(int x){}
public void main(String[] args){
}
}
La machine virtuelle Java doit-elle appeler new JavaClass(int)
? Que devrait-il passer pour x
?
Sinon, la machine virtuelle Java devrait-elle instancier JavaClass
sans exécuter de méthode de constructeur? Je pense que ce ne devrait pas être le cas, car cela concernera votre classe tout entière - parfois, vous avez une instance qui n'a pas été initialisée et vous devez la rechercher dans chaque méthode pouvant être appelée.
Il y a tout simplement trop de cas Edge et d'ambiguïtés pour qu'il soit logique que la JVM instancie une classe avant que le point d'entrée ne soit appelé. C'est pourquoi main
est statique.
Je n'ai aucune idée pourquoi main
est toujours marqué public
cependant.
Ceci est juste la convention. En fait, même le nom main () et les arguments passés sont purement conventionnels.
Lorsque vous exécutez Java.exe (ou javaw.exe sous Windows), deux appels JNI (Java Native Interface) se produisent réellement. Ces appels chargent la DLL qui est vraiment la machine virtuelle (c'est vrai - Java.exe n'est pas la machine virtuelle). JNI est l'outil que nous utilisons lorsque nous devons faire un pont entre le monde de la machine virtuelle et le monde de C, C++, etc. ... L'inverse est également vrai - il n'est pas possible (du moins à ma connaissance) d'obtenir un JVM s'exécutant sans utiliser JNI.
Fondamentalement, Java.exe est une application C très simple qui analyse la ligne de commande, crée un nouveau tableau de chaînes dans la JVM pour contenir ces arguments, analyse le nom de la classe que vous avez spécifiée comme contenant main (), utilise les appels JNI pour rechercher le La méthode main () elle-même, puis appelle la méthode main () en transmettant le tableau de chaînes nouvellement créé en tant que paramètre. Cela ressemble beaucoup à ce que vous faites lorsque vous utilisez la réflexion à partir de Java: elle utilise simplement des appels de fonctions natives, appelés de manière déroutante.
Il serait parfaitement légal pour vous d'écrire votre propre version de Java.exe (le source est distribué avec le JDK) et de le faire faire quelque chose de complètement différent. En fait, c'est exactement ce que nous faisons avec toutes nos applications basées sur Java.
Chacune de nos applications Java a son propre lanceur. Nous le faisons principalement pour obtenir notre propre icône et nom de processus, mais cela s’est avéré utile dans d’autres situations où nous souhaitons faire quelque chose en plus de l’appel main () habituel pour que tout se passe bien (par exemple, dans un cas, nous le faisons Interopérabilité COM, et nous passons en fait un descripteur COM dans main () au lieu d’un tableau de chaînes).
Donc, long et court: la raison pour laquelle il est statique est b/c c'est pratique. La raison pour laquelle on l'appelle 'main' est que cela devait être quelque chose, et main () est ce qu'ils faisaient à l'époque de C (et à cette époque, le nom de la fonction était important). Je suppose que Java.exe aurait pu vous permettre de spécifier un nom de méthode principal pleinement qualifié, au lieu de simplement la classe (Java com.mycompany.Foo.someSpecialMain) - mais cela rend simplement plus difficile pour les IDE de détecter automatiquement le ' classes "launchable" dans un projet.
La méthode main()
dans C++
, C#
et Java
est statique
Puisqu’ils peuvent ensuite être appelés par le moteur d’exécution sans / pour instancier d’objets, le code dans le corps de main()
fera le reste.
C’est ainsi que le langage Java est conçu et que la machine virtuelle Java est conçue et écrite.
Départ Chapitre 12 Exécution - Section 12.1.4 Invoke Test.main :
Enfin, une fois l'initialisation de la classe Test terminée (au cours de laquelle d'autres chargement, liaison et initialisation consécutifs peuvent s'être produits), la méthode principale de Test est appelée.
La méthode main doit être déclarée publique, statique et nulle. Il doit accepter un seul argument qui est un tableau de chaînes. Cette méthode peut être déclarée comme
public static void main(String[] args)
ou
public static void main(String... args)
Départ Chapitre 2 Concepts du langage de programmation Java - Section 2.17 Exécution :
La machine virtuelle Java commence l'exécution en appelant la méthode main d'une classe spécifiée et en lui transmettant un argument unique, qui est un tableau de chaînes. Ainsi, la classe spécifiée est chargée (§2.17.2), liée (§2.17.3) à d'autres types qu'elle utilise et initialisée (§2.17.4). La méthode main doit être déclarée publique, statique et nulle.
Téléchargez et extrayez le fichier jar source et voyez comment la machine virtuelle Java est écrite. Consultez ../launcher/Java.c
, qui contient du code C natif derrière la commande Java [-options] class [args...]
:
/*
* 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);
... ...
Supposons simplement que static
ne serait pas requis comme point d'entrée de l'application.
Une classe d'application ressemblerait alors à ceci:
class MyApplication {
public MyApplication(){
// Some init code here
}
public void main(String[] args){
// real application code here
}
}
La distinction entre le code constructeur et la méthode main
est nécessaire car, dans OO, un constructeur doit uniquement s’assurer que l’instance est initialisée correctement. Après l'initialisation, l'instance peut être utilisée pour le "service" prévu. Mettre le code d'application complet dans le constructeur gâcherait cela.
Donc, cette approche forcerait trois différents contrats sur l'application:
main
1. Ok, ce n'est pas surprenant.abstract
. Sinon, la machine virtuelle Java ne pourrait pas l'instancier.L’approche static
ne nécessite en revanche que n contrat:
main
1.Ici, ni abstract
, ni plusieurs constructeurs ne sont importants.
Puisque Java a été conçu pour être un langage simple pour l'utilisateur , il n'est pas étonnant que le point d'entrée de l'application ait également été conçu dans un moyen simple en utilisant n contrat et non de manière complexe en utilisant trois contrats indépendants et fragiles.
Remarque: cet argument est not à propos de la simplicité à l'intérieur de la JVM ou à l'intérieur du JRE. Cet argument concerne la simplicité pour le tilisateur.
Si ce n'était pas le cas, quel constructeur devrait être utilisé s'il y en a plus d'un?
Des informations supplémentaires sur l'initialisation et l'exécution des programmes Java sont disponibles dans Spécification du langage Java .
Parce que sinon, il faudrait une instance de l'objet à exécuter. Mais il doit être appelé à partir de zéro, sans construire l'objet au préalable, car il appartient généralement à la fonction main () (bootstrap) d'analyser les arguments et de construire l'objet, généralement à l'aide de ces paramètres/paramètres de programme.
Avant que la méthode principale ne soit appelée, aucun objet n'est instancié. Avoir le mot-clé static signifie que la méthode peut être appelée sans créer aucun objet au préalable.
Quel est le sens de public static void main(String args[])
?
public
est un spécificateur d'accès, ce qui signifie que tout le monde peut y accéder/l'invoquer, tel que JVM (Java Virtual Machine).static
permet à main()
d'être appelé avant la création d'un objet de la classe. Cela est nécessaire car main()
est appelé par la machine virtuelle avant que tous les objets soient créés. Comme il est statique, il peut être directement appelé via la classe.
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 */
}
}
De même, nous utilisons parfois statique pour les méthodes définies par l'utilisateur, de sorte qu'il n'est pas nécessaire de créer des objets.
void
indique que la méthode main()
en cours de déclaration ne renvoie pas de valeur.
String[] args
spécifie le seul paramètre de la méthode main()
.
args
- paramètre contenant un tableau d'objets de type classe String
.
Permettez-moi d'expliquer ces choses d'une manière beaucoup plus simple:
public static void main(String args[])
Toutes les applications Java, à l'exception des applets, démarrent leur exécution à partir de main()
.
Le mot clé public
est un modificateur d'accès permettant au membre d'être appelé de l'extérieur de la classe.
static
est utilisé parce qu'il permet d'appeler main()
sans avoir à instancier une instance particulière de cette classe.
void
indique que main()
ne renvoie aucune valeur.
Des applets, des midlets, des servlets et des beans de différents types sont construits et des méthodes de cycle de vie sont ensuite utilisées. L'appel de main est tout ce qui est fait pour la classe principale. Il n'est donc pas nécessaire qu'un état soit maintenu dans un objet appelé plusieurs fois. Il est tout à fait normal d'épingler main sur une autre classe (bien que ce ne soit pas une bonne idée), ce qui empêcherait l'utilisation de la classe pour créer l'objet principal.
C'est juste une convention, mais probablement plus pratique que l'alternative. Avec un principal statique, tout ce que vous devez savoir pour appeler un programme Java est le nom et l'emplacement d'une classe. Si ce n'était pas statique, vous devez également savoir comment instancier cette classe ou exiger que la classe ait un constructeur vide.
Lorsque vous exécutez la machine virtuelle Java (JVM) avec la commande Java
,
Java ClassName argument1 argument2 ...
Lorsque vous exécutez votre application, vous spécifiez son nom de classe en tant qu'argument de la commande Java, comme ci-dessus.
la machine virtuelle Java tente d'appeler la méthode principale de la classe que vous spécifiez
—À ce stade, aucun objet de la classe n'a été créé.
Déclarant
main
comme statiqueallows
la machine virtuelle Java àinvoke
mainwithout
créant uninstance
de la classe.
revenons à la commande
ClassName
est un command-line argument
à la machine virtuelle Java qui lui indique quelle classe exécuter. Après le nom de classe, vous pouvez également spécifier un list of Strings
(séparé par des espaces) en tant qu'arguments de ligne de commande que la machine virtuelle Java passera à votre application. -De tels arguments peuvent être utilisés pour spécifier des options (par exemple, un nom de fichier) permettant d'exécuter l'application. C'est pourquoi il existe un paramètre appelé String[] args
dans le champ principal.
Références: Programmation Java ™ (premiers objets), Dixième édition
Si la méthode principale n'est pas statique, vous devez créer un objet de votre classe principale en dehors du programme. Comment voudriez-vous faire cela?
Récemment, une question similaire a été postée sur Programmers.SE
A la recherche d'une réponse définitive d'une source primaire ou secondaire pour expliquer pourquoi (notamment) Java et C # ont décidé d'utiliser une méthode statique comme point d'entrée, plutôt que de représenter une instance d'application par une instance d'une classe
Application
, le point d'entrée étant un constructeur approprié?
TL; DR une partie de la réponse acceptée est,
En Java, la raison de
public static void main(String[] args)
est la suivante:
- (Gosling } _ voulait
- le code écrit par une personne expérimentée en C (pas en Java)
- être exécuté par une personne habituée à exécuter PostScript sur NeWS
Pour C #, le raisonnement est transitoirement similaire pour ainsi dire. Les concepteurs de langage ont gardé la syntaxe point d’entrée de programme } familière aux programmeurs venant de Java. Comme l'architecte C # Anders Hejlsberg le dit },... notre approche avec C # a simplement été d'offrir une alternative ... aux programmeurs Java ...
...
main () est statique car; à ce stade du cycle de vie de l'application, la pile d'applications est de nature procédurale car il n'y a pas encore d'objets instanciés.
C'est une table rase. Votre application est en cours d'exécution à ce stade, même sans qu'aucun objet ne soit déclaré (rappelez-vous qu'il existe des modèles de codage procéduraux AND OO). En tant que développeur, vous transformez l'application en une solution orientée objet en créant des instances de vos objets et en fonction du code compilé à l'intérieur.
Orienté objet est idéal pour des millions de raisons évidentes. Cependant, le temps est révolu où la plupart des développeurs VB utilisaient régulièrement des mots-clés tels que "goto" dans leur code. "goto" est une commande de procédure dans VB qui est remplacée par son équivalent OO: invocation de méthode.
Vous pouvez également regarder le point d’entrée statique (principal) en tant que liberté pure. Si Java avait été suffisamment différent pour instancier un objet et ne vous présenter que cette instance, vous n'auriez pas le choix MAIS écrire une application procédurale. Aussi inimaginable que cela puisse paraître pour Java, il est possible que de nombreux scénarios nécessitent des approches procédurales.
C'est probablement une réponse très obscure. Rappelez-vous que "classe" est seulement une collection de code inter-relié. "Instance" est une génération autonome isolée, vivante et respirante de cette classe.
Le prototype public static void main(String[])
est une convention définie dans le JLS :
La méthode main doit être déclarée publique, statique et nulle. Il doit spécifier un paramètre formel (§8.4.1) dont le type déclaré est array of String.
Dans la spécification JVM 5.2. Démarrage de la machine virtuelle nous pouvons lire:
La machine virtuelle Java démarre en créant une classe initiale, spécifiée de manière dépendante de l'implémentation, à l'aide du chargeur de classes d'amorçage (§ 5.3.1). La machine virtuelle Java lie ensuite la classe initiale, l'initialise et appelle la méthode de classe publique void main (String []). L'appel de cette méthode entraîne toute exécution ultérieure. L'exécution des instructions de la machine virtuelle Java constituant la méthode principale peut entraîner la liaison (et par conséquent la création) de classes et d'interfaces supplémentaires, ainsi que l'appel de méthodes supplémentaires.
Chose amusante, dans la spécification JVM, il n'est pas mentionné que la méthode principale doit être statique . Mais la spécification indique également que la machine virtuelle Java effectue les 2 étapes précédentes:
L'initialisation d'une classe ou d'une interface consiste à exécuter sa méthode d'initialisation de classe ou d'interface.
Dans 2.9. Méthodes spéciales :
Une méthode d'initialisation de classe ou d'interface est définie:
Une classe ou une interface a au plus une méthode d'initialisation de classe ou d'interface et est initialisée (§5.5) en invoquant cette méthode. La méthode d'initialisation d'une classe ou d'une interface a le nom spécial
<clinit>
, ne prend aucun argument et est vide.
Et un méthode d'initialisation de classe ou d'interface est différent d'un méthode d'initialisation d'instance défini comme suit:
Au niveau de la machine virtuelle Java, chaque constructeur écrit dans le langage de programmation Java (JLS §8.8) apparaît sous la forme d'une méthode d'initialisation d'instance ayant le nom spécial
<init>
.
Ainsi, la machine virtuelle Java initialise une méthode d'initialisation de classe ou d'interface et non une méthode d'initialisation d'instance qui est en fait un constructeur . Il n'est donc pas nécessaire de mentionner que la méthode principale a être statique dans la spécification de la machine virtuelle Java, car elle est impliquée par le fait qu'aucune instance n'est créée avant l'appel de la méthode main.
Je pense que le mot clé 'static' fait de la méthode principale une méthode de classe et que les méthodes de classe n'en ont qu'une copie et peuvent être partagées par tous. De plus, il ne nécessite pas d'objet pour référence. Ainsi, lorsque la classe de pilotes est compilée, la méthode main peut être invoquée. (Je suis juste au niveau alphabet de Java, désolé si je me trompe)
C'est juste une convention. La JVM pourrait certainement traiter avec des méthodes principales non statiques si cela aurait été la convention. Après tout, vous pouvez définir un initialiseur statique sur votre classe et instancier un zillion d’objets avant d’avoir accès à votre méthode main ().
Le mot clé public
est un modificateur d'accès permettant au programmeur de contrôler La visibilité des membres de la classe. Lorsqu'un membre de la classe est précédé de public
, ce membre Peut être accédé par le code en dehors de la classe dans laquelle il est déclaré.
L'opposé de public
est private
, ce qui empêche un membre d'être utilisé par du code défini en dehors de sa classe.
Dans ce cas, main()
doit être déclaré en tant que public
, puisqu'il doit être appeléby code en dehors de sa classe au démarrage du programme.
Le mot clé static
permet à main()
d'être appelée sans avoir à instancier une instance particulière de la classe. Cela est nécessaire car main()
est appelé par l'interpréteur Java avant la création d'objets.
Le mot clé void
indique simplement au compilateur que main()
ne renvoie pas de valeur.
static - Lorsque la machine virtuelle Java appelle la méthode main, il n'existe pas d'objet pour la classe appelée. Elle doit donc avoir une méthode statique pour autoriser l'appel de la classe.
Le véritable point d’entrée de toute application est une méthode statique. Si le langage Java prend en charge une méthode d'instance en tant que "point d'entrée", le runtime devra alors l'implémenter en interne en tant que méthode statique qui construit une instance de l'objet suivie de l'appel de la méthode d'instance.
Cela étant fait, j'examinerai la raison pour laquelle j'ai choisi une des trois options suivantes:
static void main()
telle que nous la voyons aujourd'hui.void main()
a appelé un objet nouvellement construit.Program
, l'exécution sera alors constituée de new Program()
).static void main()
main()
.void main()
new ClassName()
.main()
.new ClassName()
Je vais en sens inverse pour celui-ci.
Gardez à l’esprit que l’un des objectifs de Java était de mettre l’accent sur (dans la mesure du possible, de bonnes pratiques) de programmation orientée objet. Dans ce contexte, le constructeur d'un objet initialise l'objet, mais ne devrait pas être responsable du comportement de cet objet. Par conséquent, une spécification qui donne un point d'entrée new ClassName()
pourrait confondre les nouveaux développeurs Java en forçant une exception à la conception d'un constructeur "idéal" pour chaque application.
En faisant de main()
une méthode d'instance, le problème ci-dessus est certainement résolu. Cependant, cela crée une complexité en imposant à la spécification de répertorier la signature du constructeur de la classe d'entrée ainsi que la signature de la méthode main()
.
En résumé, spécifier une static void main()
crée une spécification avec la moindre complexité tout en adhérant au principe de placement du comportement dans les méthodes. Considérant à quel point il est simple d'implémenter une méthode main()
qui construit elle-même une instance d'une classe et appelle une méthode d'instance, il n'y a aucun avantage réel à spécifier main()
en tant que méthode d'instance.
Je ne sais pas si la machine virtuelle Java appelle la méthode principale avant l’instanciation des objets ... Mais il existe une raison bien plus puissante pour laquelle la méthode main () est statique ... Lorsque la machine virtuelle Java appelle la méthode principale de la classe (par exemple, , La personne). il l'invoque par " Person.main () ". Vous voyez, la JVM l'appelle par le nom de la classe. C'est pourquoi la méthode main () est supposée être statique et publique afin que la JVM puisse y accéder.
J'espère que ça a aidé. Si c'est le cas, faites le moi savoir en commentant.
la méthode main doit toujours être statique car, à l'exécution, JVM ne crée aucun objet à appeler méthode principale. Comme nous le savons en Java, les méthodes statiques sont les seules méthodes pouvant être appelées à l'aide du nom de classe. Les méthodes principales doivent donc toujours être statiques.
pour plus d'informations, visitez cette vidéo: https://www.youtube.com/watch?v=Z7rPNwg-bfk&feature=youtu.be
Toute méthode déclarée comme statique en Java appartient à la classe elle-même . Encore une fois, la méthode statique d'une classe particulière est accessible uniquement en faisant référence à la classe telle que Class_name.method_name();
Donc, une classe n'a pas besoin d'être instanciée avant d'accéder à une méthode statique.
Ainsi, la méthode main () est déclarée en tant que static
afin de pouvoir y accéder sans créer un objet de cette classe.
Puisque nous sauvegardons le programme avec le nom de la classe où la méthode principale est présente (ou à partir duquel le programme doit commencer son exécution, applicable pour les classes sans méthode main()
() (niveau avancé)). Donc, de la manière mentionnée ci-dessus:
Class_name.method_name();
la méthode principale est accessible.
En résumé, lorsque le programme est compilé, il recherche la méthode main()
ayant des arguments String
tels que: main(String args[])
dans la classe mentionnée (c'est-à-dire par le nom du programme) et La méthode main () est déclarée comme statique.
Les mots-clés voic static publics signifient que l'interpréteur de machine virtuelle Java (JVM) peut appeler la méthode principale du programme pour démarrer le programme (public) sans créer d'instance de la classe (statique), et le programme ne renvoie pas de données à Java. VM interprète (vide) à la fin.
Source: Les bases, Partie 1, Leçon 2: Applications de construction
Les méthodes statiques ne nécessitent aucun objet. Il fonctionne directement, donc principal fonctionne directement.
il y a une raison simple derrière cela parce que object n'est pas obligé d'appeler une méthode statique. Si c'était une méthode non statique, la machine virtuelle Java crée un objet en premier, puis une méthode main (), ce qui poserait le problème de l'allocation de mémoire supplémentaire.
C'est juste une convention comme on peut le voir ici:
La méthode doit être déclarée publique et statique, elle ne doit en retourner aucun value, et il doit accepter un tableau String en tant que paramètre. Par défaut, le premier argument sans option est le nom de la classe à appeler . Un nom de classe complet doit être utilisé. Si l'option -jar est spécifié, le premier argument sans option est le nom d'une archive JAR contenant les fichiers de classe et de ressources pour l'application, avec le fichier classe de démarrage indiquée par l'en-tête du manifeste Main-Class.
http://docs.Oracle.com/javase/1.4.2/docs/tooldocs/windows/Java.html#description
De Java.Sun.com (il y a plus d'informations sur le site):
La méthode principale est statique pour donner à l'interpréteur Java VM un moyen de démarrer la classe sans créer d'abord une instance de la classe de contrôle. Des instances de la classe de contrôle sont créées dans la méthode principale après le démarrage du programme.
Ma compréhension a toujours été simplement que la méthode principale, comme toute méthode statique, peut être appelée sans créer une instance de la classe associée, ce qui lui permet de s’exécuter avant tout autre élément du programme. Si ce n'était pas statique, vous devriez instancier un objet avant de l'appeler, ce qui crée un problème de type «poule et œuf», car la méthode principale correspond généralement à celle utilisée pour instancier des objets au début du programme.
Fondamentalement, nous définissons les DATA MEMBERS et MEMBER FUNCTIONS en tant que STATIC qui n’effectuent aucune tâche liée à un objet. Et dans le cas de la méthode main, nous le faisons en tant que STATIC car cela n’a rien à voir avec un objet, car la méthode main est toujours exécutée, que nous créons un objet ou non.
La clé statique Word dans la méthode principale est utilisée car aucune instanciation n'a lieu dans la méthode principale. Mais l’objet est construit et non l’appel; nous utilisons la clé statique Word dans la méthode principale . Dans jvm, la mémoire contextuelle est créée lors du chargement de la classe. si nous faisons la statique principale maintenant, elle sera en mémoire et pourra être accessible à jvm (class.main (..)) afin que nous puissions appeler la méthode main sans que le besoin de tas ait été créé.