web-dev-qa-db-fra.com

Principal est-il un identifiant valide Java?

Un de mes enfants suit Java au lycée et a passé ce test à l'un de ses tests:

Lequel des éléments suivants est un identifiant valide en Java?

une. 123Java
b. main
c. Java1234
ré. {abce
e. )whoot

Il a répondu b et s'est trompé.

J'ai examiné la question et soutenu que main est un identificateur valide et qu'il aurait dû être correct.

Nous avons jeté un œil à la Java spec pour les identificateurs et cela a renforcé ce point. Nous avons également écrit un exemple de programme contenant une variable appelée main, ainsi qu'une méthode. Il a créé une réfutation écrite incluant la référence de la documentation Java, le programme de test et le professeur l'ignorant, indiquant que la réponse était toujours incorrecte.

Est-ce que main est un identifiant valide?

285
Gary Bak
public class J {
    public static void main(String[] args)
    {
        String main = "The character sequence \"main\" is an identifier, not a keyword or reserved Word.";
        System.out.println(main);
    }
}

Ceci compile, et lorsqu'il est exécuté, émet cette sortie:

The character sequence "main" is an identifier, not a keyword or reserved Word.

La séquence de caractères main est un identifiant et non un mot clé ou un mot réservé.

Le section pertinente du JLS est 3.8 :

Un identifiant est une séquence de longueur illimitée de lettres Java et chiffres Java , dont le premier doit être une lettre Java .

Identifiant:

IdentifierChars mais pas un mot-clé ou BooleanLiteral ou NullLiteral

IdentifierChars:

JavaLetter {JavaLetterOrDigit}

JavaLetter:

tout caractère Unicode qui est une "lettre Java"

JavaLetterOrDigit:

tout caractère Unicode qui est une "lettre ou chiffre Java"

La séquence de caractères main correspond à la description ci-dessus et ne figure pas dans la liste liste de mots-clés de la section 3.9 .

(La séquence de caractères Java1234 est également un identifiant, pour les mêmes raisons.)

252
rgettman

main est un identifiant Java valide et le professeur se trompe.

La documentation correspondante se trouve dans la spécification de langage Java, ici:

Chapitre 3. "Structure lexicale", section 3.8. "Identifiants":

https://docs.Oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8

Ça dit:

Un identifiant est une suite de longueur illimitée de Java lettres et de Java chiffres, dont le premier doit être une Java lettre ... Un identifiant ne peut pas avoir Même orthographe (séquence de caractères Unicode) qu'un mot clé (§3.9), un littéral booléen (§3.10.3) ou le littéral nul (§3.10.7), ou une erreur lors de la compilation se produit.

Cela signifie que vous pouvez prouver qu'il s'agit d'un identifiant valide en l'utilisant comme identifiant et en observant qu'aucune erreur de compilation ne se produit.

94
Mike Nakis

Comme le dit l'autre réponse

main est un identifiant Java valide, ainsi que Java1234.

Je suppose que la confusion vient du fait que la méthode main(String[]) est souvent utilisée comme point d’entrée par la JVM.1. Cependant, cela ne signifie pas que le jeton main lui-même ne peut pas être utilisé comme identifiant2.

Les spécifications le disent, et les déclarations suivantes sont également valides:

  • Un champ:

    private int main;
    
  • Une variable locale:

    String main = "";
    
  • Une méthode:

    private void main() { ... }
    
  • Une classe (bien qu'un nom de classe commençant par une minuscule soit déconseillé):

    public class main { ... }
    
  • Un paquet:

    package main;
    

1: Comme indiqué dans les commentaires, la spécification JVM elle-même n’impose aucune méthode particulière comme point d’entrée, mais l’outil largement utilisé Java utilise souvent une telle méthode comme point d’entrée.
2: J'éviterais généralement de créer une méthode principale autre que main(String[]).

76
MC Emperor

Ceci compile bien sur Java 1.8 ...

public class main {

    public String main = "main"; 

    public void main(String main) {
        System.out.println("This object is an instance of the class " + this.getClass().getCanonicalName());
        System.out.println("The value of the argument \"main\" for this call to the method \"main(String main)\" is " + main);
        System.out.println("The value of the field \"main\" is " + this.main);
    }

    public static void main(String[] args) {
        main main = new main();
        main.main(main.main + main.main);
    }
}

... et lorsqu'il est exécuté produit la sortie:

This object is an instance of the class main
The value of the argument "main" for this call to the method "main(String main)" is mainmain
The value of the field "main" is main
64
MichaelK

J'ai jeté tout ce que je pouvais, et ça a l'air de marcher. Je dirais que principal est un identifiant valide.

package main;

public class main {

    static main main;
    String Main;

    main(String main) {
        Main = main;
    }

    main(main main) {
        System.out.println(main.Main);
    }

    main main(main main) {
        return new main(main);
    }

    public static void main(main...Main) {
        main:
        for (main main : Main) {
            main = (main instanceof Main) ? new main(main): main.main(main);
            break main;
        }
    }

    public static void main(String[] args) {
        main = new main("main");
        main.main(main, main);
        main = main.new Main(main) {
            main main(main main) {
                return ((Main)main).main();
            }
        };
        main.main(main);
        main.main(main,main);
    }

    abstract class Main extends main {
        Main(main main) {
            super("main");
        }

        main main() {
            main.Main = "Main";
            return main;
        }
    }
}
44
18107

Comment main ne peut pas être utilisé comme identifiant alors qu'il est utilisé comme identifiant pour déclarer la méthode "main"?

Pour un langage aussi classique:

public class Foo{
   public static void main(String[] args){
   }
}

main n'est pas un mot clé et ce ne sera probablement jamais un mot clé dans Java pour des raisons évidentes de compatibilité rétro.


À propos de la question, main est-il un bon identifiant?

Premièrement: valable pour un compilateur ne veut pas forcément dire bon.
Par exemple, l'option Java1234 proposée est également un identificateur valide, mais il convient de l'éviter.

main a un sens très particulier et important: il est utilisé comme méthode de point d’entrée des classes et des jars exécutés par la ligne de commande Java.
Utiliser main pour un nom de méthode qui ne remplit pas les critères à utiliser par la ligne de commande Java serait trompeur, mais son utilisation en tant que nom de variable ou nom de classe pourrait créer sens.
Par exemple, définir la classe représentant le point d’entrée d’une application en tant que classe Main de l’application est acceptable et l’utiliser ainsi comme nom de variable, par exemple:

public class Main {

  public static void main(String args[]){
     Main main = new Main();
     // ...
  }      

}

De manière générale, en Java, plusieurs caractères ou "mots" sont considérés comme des identifiants valides pour le compilateur, mais il est vivement déconseillé de les utiliser dans le code client (mais le code généré peut le faire: classes imbriquées par exemple), car ils ne sont pas lisibles et/ou vraiment trompeur.

Par exemple, cela pourrait être valable pour le compilateur:

public class Object { // 1
    public void foo() {
       ...
    }
}

public class BadChosenIdentifier {

    public static void main() { // 2
        new BadChosenIdentifier().toString(new Object());  
    }

    public void toString(Object Java1234) { // 3, 4
        String _result$ = Java1234 + " -> to avoid"; // 4
        System.out.println(_result$);
    }    
}

Mais nous ne voulons pas:

  • nommer Object notre classe telle qu'elle est définie dans Java.lang (1).
  • nommer une méthode main() si ne remplit pas les critères à utiliser par la ligne de commande Java (2).
  • surcharger la méthode Object.toString() (3).
  • pour nommer nos variables avec _, $ ou tout autre caractère surprenant/sans signification qui va à l’encontre des conventions de dénomination partagées (4).
44
davidxxx

Est-ce un identifiant valide? Oui.

Est-ce un bon identifiant? Pas si vous l'utilisez pour autre chose que la méthode qui commence au lancement de la machine virtuelle Java.

Un autre identifiant valide est-il répertorié? Oui.

Les instructions de test disent-elles de choisir la meilleure réponse?

40
user1423956

main est parfaitement valide car, de la documentation :

  1. Est une "séquence de Java lettres et de Java chiffres, dont le premier est une Java lettre"
  2. N'est-ce pas un mot-clé
  3. N’est pas un littéral booléen i.e. "vrai" ou "faux"
  4. N'est-ce pas littéral nul
31
zero298
public class Main {
    private static String main;
    public static void main(String[] main) {
        Main.main = main[0];
        new Main().main(Main.main);
    }
    private void main(String main) {
        System.out.println(main);
    }
}
29
kabra.dabar

Cet enseignant a commis une erreur mineure en supposant que principal n’est pas un identifiant valide ou tout simplement en formulant la question de manière erronée. Il voulait peut-être dire "un bon identifiant".
Mais ignorer les arguments de vos fils et décourager ainsi son approche scientifique consistant à vérifier la littérature pertinente (spécification Java) et à effectuer une expérience (écriture d'un programme exemple) est le exact opposé de ce qu'est un enseignant censé faire.

7
user82593
  1. Devrait être un seul mot. C'est que les espaces ne sont pas autorisés.

    Exemple: mangoprice est valide mais le prix de la mangue n'est pas valide.

  2. Devrait commencer par une lettre (alphabet) ou un trait de soulignement ou un symbole $.

    Exemple: price, _price et $ price sont des identificateurs valides.

  3. Ne doit pas être un mot clé de Java, car ce mot clé a une signification particulière pour le compilateur.

    Exemple: classe ou vide, etc.

  4. Ne doit pas commencer par un chiffre mais le chiffre peut être au milieu ou à la fin.

    Exemple: 5mangoescost n'est pas valide et mango5cost et mangocost5 sont valides.

  5. La longueur d'un identifiant dans Java peut comporter 65 535 caractères. Tous sont significatifs. Les identifiants sont sensibles à la casse. La mangue et la mangue sont traitées différemment. Peut contenir toutes les lettres majuscules ou minuscules ou un mélange.

IDENTIFIER: ce sont des noms de classes, noms de méthodes, noms de variables ...

Comme principal n'est pas un mot réservé et selon les explications ci-dessus pour définir un identifiant principal est un identifiant valide et Java1234 également.Les options restantes ne sont pas valides en raison de l'explication ci-dessus .

5
subhashis

main et Java123 sont des identificateurs valides, le mot clé n'est pas un mot clé réservé; son utilisation est donc parfaitement acceptable. Dans la mesure du test, vous devriez avoir obtenu un point. ou un demi-point au moins.

5
shavar