540 votes

Pourquoi est la méthode principale de Java statique ?

La signature de méthode d’une méthode principale de Java est :

Y a-t-il une raison pour que cette méthode statique ?

437voto

Kevin Day Points 9446

C'est juste de la convention. En fait, le nom même main(), et les arguments passés en sont de pure convention.

Lorsque vous exécutez java.exe (ou javaw.exe sur Windows), ce qui se passe vraiment est un couple de Java Native Interface (JNI) appels. Ces appels de charger la DLL qui est vraiment la JVM (c'est le droit - java.exe n'est PAS la JVM). JNI est l'outil que nous utilisons lorsque nous avons à faire le pont entre la machine virtuelle monde, et le monde de C, C++, etc... L'inverse est également vrai - il n'est pas possible (à ma connaissance) à réellement obtenir une JVM en cours d'exécution sans l'aide de JNI.

Fondamentalement, java.exe est super simple C application qui analyse la ligne de commande, crée un nouveau tableau de Chaîne dans la JVM de tenir ces arguments, analyse le nom de la classe que vous avez spécifié comme contenant de main(), utilise JNI appels de trouver la méthode main (), puis appelle la méthode main (), en passant dans la chaîne nouvellement créée tableau comme paramètre. C'est très, très semblable à ce que vous faites lorsque vous utilisez la réflexion de Java, il utilise juste prêter à confusion du nom des appels de fonction native à la place.

Il serait parfaitement légal pour vous d'écrire votre propre version de java.exe (la source est distribué avec le JDK), et de faire quelque chose d'entièrement différent. En fait, c'est exactement ce que nous faisons avec tous nos basé sur Java apps.

Chacune de nos applications Java dispose de son propre lanceur. Nous avons principalement ce faire, nous avons donc notre propre icône et le nom du processus, mais il est utile dans d'autres situations où nous voulons faire quelque chose de plus que l'habituel main() appel pour faire avancer les choses (Par exemple, dans un cas, nous faisons l'interopérabilité COM, et nous fait passer un COM poignée dans main() à la place d'un tableau de chaînes).

Donc, à long et court: la raison pour laquelle il est statique est b/c qui est pratique. La raison pour laquelle il est appelé "principal" est parce qu'il avait quelque chose, et main() est ce qu'ils ont fait dans les vieux jours de C (et dans ces jours, le nom de la fonction est importante). Je suppose que java.exe pourrait avoir permis de vous il suffit de spécifier complet de la méthode principale de ce nom, au lieu de simplement la classe (java com.myompany.Foo.someSpecialMain) -, mais cela rend plus difficile sur IDEs d'auto-détecter le "projetables" classes dans un projet.

354voto

Jacob Krall Points 10327

La méthode est statique, car sinon il n'y aurait 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){
  }
}

Si la JVM d'appel de la nouvelle JavaClass(int)? Que faut-il passer pour x?

Si non, la JVM instancier JavaClass sans courir aucun constructeur méthode? Je pense que ça ne devrait pas, parce que ce sera spécial de cas sur l'ensemble de votre classe - parfois, vous avez une instance qui n'a pas été initialisé, et vous devez les vérifier dans chaque méthode qui pourrait être appelé.

Il y a trop de cas limites et ambiguïtés pour qu'elle ait un sens pour la JVM d'avoir à instancier une classe avant le point d'entrée est appelé. C'est pourquoi le principal est statique.

Je n'ai aucune idée de la raison principale est toujours marqué le public .

197voto

Noah Goodrich Points 12645

La méthode main () en C ++, C # et Java est statique car ils peuvent être invoqués par le moteur d'exécution sans avoir à instancier une instance de la classe parente.

42voto

A.H. Points 23369

Nous allons tout simplement faire semblant, que static ne serait pas nécessaire car l'application de point d'entrée.

Une application de classe 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 du constructeur et de l' main méthode est nécessaire, parce que dans OO parler d'un constructeur doit s'assurer, qu'une instance est initialisé correctement. Après l'initialisation de l'instance peut être utilisé pour le "service". Mettre la totalité de l'application du code dans le constructeur serait gâcher.

Donc, cette approche permettrait de force trois contrats différents sur l'application:

  • Il doit être un constructeur par défaut. Sinon, la JVM ne sais pas quel constructeur à appeler et quels paramètres doivent être fournis.
  • Il doit être un main méthode1. Ok, ce n'est pas surprenant.
  • La classe ne doit pas être abstract. Sinon, la JVM ne pouvait pas l'instancier.

L' static approche sur l'autre main ne nécessite un contrat:

  • Il doit y avoir un main méthode1.

Ici, ni abstract pas plusieurs constructeurs n'ont pas d'importance.

Depuis Java a été conçu pour être un langage simple pour l'utilisateur, il n'est pas surprenant que l'application point d'entrée a été conçu de façon simple à l'aide d'un contrat et non d'une façon complexe à l'aide de trois indépendants et cassants contrats.

Veuillez noter: Cet argument n'est pas à propos de la simplicité à l'intérieur de la JVM ou à l'intérieur de la JRE. Cet argument se fonde sur la simplicité pour l' utilisateur.


1

La complète ici signature compte comme un seul contrat.

41voto

yorkw Points 24676

Pourquoi le public static void main(String[] args) ?

C'est la façon dont le Langage Java est conçu et Java Virtual Machine est conçue et écrite.

Oracle Java Language Specification

Consultez le Chapitre 12 de l'Exécution de l'Article 12.1.4 Invoquer Test.principales:

Enfin, après l'achèvement de l'initialisation d'une classe de Test (au cours de laquelle d'autres dommages de chargement, de liant, et de l'initialisation peut avoir eu lieu), la méthode principale de Test est invoquée.

La méthode principale doit être déclarée public, statique, et non avenu. Il doit accepter qu'un seul argument qui est un tableau de chaînes de caractères. Cette méthode peut être déclarée comme

public static void main(String[] args)

ou

public static void main(String... args)

Oracle Java Virtual Machine Spécification

Découvrez Chapitre 2 le Langage de Programmation Java Concepts - Section 2.17 Exécution:

La machine virtuelle Java commence l'exécution en invoquant la méthode principale de certaines classe et en passant un seul argument, qui est un tableau de chaînes de caractères. Cela provoque la classe spécifiée à charger (§2.17.2), lié (§2.17.3) à d'autres types qu'il utilise, et initialisé (§2.17.4). La méthode principale doit être déclarée public, statique, et non avenu.

Oracle OpenJDK Source

Télécharger et extraire la source de pot et de voir comment la JVM est écrit, découvrez ../launcher/java.c, qui contient le code C code de 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);

... ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X