Main è un identificatore Java valido?


288

Uno dei miei figli sta prendendo Java al liceo e lo ha fatto in uno dei suoi test:

Quale dei seguenti è un identificatore valido in Java?

un. 123java
b. main
c. java1234
d. {abce
e. )whoot

Ha risposto b e ha sbagliato.

Ho esaminato la domanda e ho sostenuto che si main tratta di un identificatore valido e che avrebbe dovuto essere giusto.

Abbiamo dato un'occhiata alle specifiche Java per gli identificatori e ha rafforzato questo punto. Abbiamo anche scritto un programma di esempio con una variabile chiamata main, oltre a un metodo. Ha creato una confutazione scritta che includeva il riferimento alla documentazione Java, il programma di test e l'insegnante l'hanno ignorato e ha detto che la risposta è ancora errata.

È mainun identificatore valido?


12
Mi rende sempre triste vedere un insegnante così insicuro che ha paura di imparare qualcosa di nuovo e ammettere un errore.
Ryan Lundy,

credo di si. ma non dovresti davvero usarlo come nome di variabile / metodo (nonostante il caso ovvio), quindi se l'insegnante sta cercando di perforare il punto a casa per essere premuroso, specialmente in questo caso, i nomi dei metodi allora posso vedere il suo / il suo punto.
Bharal,

3
Questa domanda fa davvero, se l'insegnante di tuo figlio sta facendo il suo lavoro correttamente? Vedo due identificatori Java validi. Quindi la risposta è 'b' E 'c'. Quindi l'insegnante ha ragione. Oppure mi sfugge qualcosa?. Come può essere una domanda SO? A giudicare da una persona che non fa nemmeno parte della comunità ...
jschnasse

1
Questa è una domanda sugli insegnanti, non su Java.
ACV

1
Un altro di quei casi "ingannati dalla tua domanda ingannevole"; gli insegnanti dovrebbero davvero almeno dare un'occhiata alle specifiche della lingua prima di provare a scrivere una domanda d'esame come questa.
jrh

Risposte:


253
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);
    }
}

Questo compila e, quando eseguito, emette questo output:

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

La sequenza di caratteri mainè un identificatore, non una parola chiave o una parola riservata.

La sezione pertinente del JLS è 3.8 :

Un identificatore è una sequenza di lettere e cifre Java di lunghezza illimitata , la prima delle quali deve essere una lettera Java .

Identifier:

    IdentifierChars ma non una parola chiave o BooleanLiteral o NullLiteral

IdentifierChars:

    JavaLetter {JavaLetterOrDigit}

JavaLetter:

    qualsiasi carattere Unicode che sia una "lettera Java"

JavaLetterOrDigit:

    qualsiasi carattere Unicode che sia una "lettera o cifra Java"

La sequenza di caratteri si mainadatta alla descrizione sopra e non è nell'elenco delle parole chiave nella Sezione 3.9 .

(La sequenza di caratteri java1234è anche un identificatore, per gli stessi motivi.)


25
@Clockwork La domanda era formulata in modo tale che una sola scelta potesse essere corretta. Tuttavia, entrambe le scelte b e c soddisfatto le condizioni del problema, in contrasto con la scelta implicita. Ciò ha lasciato al bambino del PO di scegliere tra quale risposta corretta era l'unica che l'insegnante riteneva corretta.
rgettman,

@rgettman ho letto " Quale delle seguenti ... " come consentire più di una volta la scelta, a cui " bec " sarebbe una risposta valida.
TripeHound,

6
@TripeHound "è un identificatore valido" è singolare e richiede esattamente 1 risposta. Confrontalo con "sono identificatori validi"
Dammi il 411

2
Avresti potuto fare anche la lezione main;)
Peter Lawrey,

97

main è un identificatore Java valido e l'insegnante ha torto.

La documentazione pertinente si trova nelle specifiche del linguaggio Java, proprio qui:

Capitolo 3. "Struttura lessicale", sezione 3.8. "identificatori":

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

Dice:

Un identificatore è una sequenza di lettere e cifre Java di lunghezza illimitata, la prima delle quali deve essere una lettera Java ... Un identificatore non può avere la stessa ortografia (sequenza di caratteri Unicode) di una parola chiave (§3.9), letterale booleano §3.10.3) o il valore letterale null (§3.10.7) o si verifica un errore di compilazione.

Ciò significa che puoi provare che si tratta di un identificatore valido:

  • cercandolo nell'elenco delle parole chiave java (suggerimento: non lo troverai lì!) o semplicemente da
  • usandolo come identificatore e osservando che non si verificano errori durante la compilazione.

1
Potresti citare e precisarlo in modo più esplicito?
zero298,

36
no, perché è un'intera sezione. Se l'insegnante pensa che questa sezione faccia una sorta di eccezione per "principale", è l'insegnante che deve mostrare dove lo dice.
Mike Nakis,

76

Come affermano le altre risposte

mainè un identificatore Java valido , nonché java1234.

Immagino che la confusione derivi dal fatto che il main(String[])metodo è spesso usato come punto di ingresso da JVM 1 . Tuttavia, ciò non significa che il token mainstesso non possa essere utilizzato come identificatore 2 .

Le specifiche lo dicono e sono valide anche le seguenti dichiarazioni:

  • Un campo:

    private int main;
  • Una variabile locale:

    String main = "";
  • Un metodo:

    private void main() { ... }
  • Una classe (anche se un nome di classe che inizia con lettere minuscole è sconsigliato):

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

    package main;

1: Come notato nei commenti, la specifica JVM stessa non impone alcun metodo particolare come punto di ingresso, ma lo javastrumento ampiamente utilizzato spesso utilizza un metodo come punto di ingresso.
2: Eviterei generalmente di creare un metodo principale diverso da main(String[]).


22
"Suppongo che la confusione derivi dal fatto che il metodo principale (String []) viene utilizzato come punto di ingresso per la JVM." mainnon è il punto di ingresso per la JVM. È il punto di ingresso javautilizzato dallo strumento per eseguire le applicazioni. Altri strumenti (contenitori servlet, ad esempio) utilizzano altri punti di ingresso.
TJ Crowder,

27
che è ancora più ironico, perché anche nel "contesto del punto di ingresso" principale È GIÀ UN identificativo valido. Quindi anche il caso che potresti
opporvi

@TJCrowder Grazie, l'ho incluso nella risposta.
MC Emperor

1
@Hobbamok Sembri confuso sui concetti di base di Java, il che probabilmente spiega perché lo insegni in una scuola e non praticare è la risposta che mi viene in mente
rath

4
Lo javastrumento non richiede un main(String[])metodo se la classe principale estende javafx.application.Application .
VGR,

65

Questo si compila bene su 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);
    }
}

... e quando eseguito produce l'output:

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

5
È possibile aggiungere un altro static mainmetodo con parametri diversi?
jpmc26,

6
@ jpmc26 Provalo e raccontaci come è andata. :)
MichaelK,

1
Beh, questo è un sacco di alimentazione
MC Emperor

4
@MCEmperor Sì, questo è il mio argomento principale per la mia risposta. ;)
MichaelK,

3
Hai dimenticato di aggiungere package main;!
Solomon Ucko,

45

Ho gettato tutto quello che potevo, e sembra funzionare. Direi che main è un identificatore valido.

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;
        }
    }
}

2
Mi piace. Prova un 'grep -o main main.java | wc -l '
Gary Bak,

3
Quel codice mi ricorda il linguaggio di programmazione "ook" ^^ Quasi tutte le parole di questo codice sono "principali" ...
Florian Bach,

public static void main(main...Main)( manca uno spazio ) non può funzionare, vero?
GeroldBroser ripristina Monica il

3
Sento di averlo integrato.
Ross Presser,

1
@GeroldBroser Questo è più pulito, ma non strettamente necessario: gli spazi bianchi tra i token sono in molti casi facoltativi, sono necessari solo quando la concatenazione di due token successivi sarebbe altrimenti valida.
MC Emperor

44

Come mainpotrebbe non essere usato come identificatore mentre è usato come identificatore per dichiarare il metodo "principale"?

Per un linguaggio così classico:

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

main non è una parola chiave e probabilmente non sarebbe mai una parola chiave in Java per ovvi motivi di retro compatibilità.


A proposito della domanda, è mainun buon identificatore?

Primo: valido per un compilatore non significa necessariamente buono.
Ad esempio, l' java1234opzione che viene proposta è anche un identificatore valido ma che dovrebbe davvero essere evitato.

mainha un significato molto particolare e importante: viene utilizzato come metodo del punto di ingresso di classi e vasetti eseguiti dalla javariga di comando.
L'uso maindi un nome di metodo che non soddisfa i criteri da utilizzare dalla javariga di comando sarebbe fuorviante mentre lo si utilizza come nome di variabile o nome di classe potrebbe avere senso.
Ad esempio, definire la classe che rappresenta il punto di ingresso di un'applicazione come Mainclasse dell'applicazione è accettabile e quindi usarlo anche come nome di variabile come:

public class Main {

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

}

In generale, in Java, più caratteri o "parole" sono considerati identificatori validi per il compilatore ma sono fortemente sconsigliati di essere utilizzati nel codice client (ma il codice generato può farlo: classi nidificate ad esempio) come non leggibili e / o davvero fuorviante.

Ad esempio, questo potrebbe essere valido per il compilatore:

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$);
    }    
}

Ma non vogliamo:

  • nominare la Objectnostra classe come questa è definita in java.lang(1).
  • nominare un metodo main()se non soddisfa i criteri da utilizzare dalla javariga di comando (2).
  • per sovraccaricare il Object.toString()metodo (3).
  • nominare le nostre variabili con _, $o qualsiasi carattere sorprendente / indesiderato che vada contro le convenzioni di denominazione condivise (4).

7
Solo per notare, mainpotrebbe essere una parola chiave che può essere utilizzata solo come nome per un metodo statico con una firma appropriata (o qualsiasi altra cosa). Nota che le chiamate di classe super usano superin un modo che lo fa sembrare un identificatore: super(foo);e super.foo, ma superÈ una parola chiave (e prima che i generici fossero aggiunti, questo era l'unico modo per usarlo (che posso ricordare)).
jaxad0127,

@ jaxad0127 Punto interessante ma non sono completamente d'accordo. In realtà non lo è e in futuro probabilmente non potrebbe esserlo per motivi di compatibilità ancora. Se hai definito mainuna parola chiave in una nuova versione di Java, significa che qualsiasi codice che utilizza main come nome del metodo (o nomi di membri) non verrà più compilato. L'uso di superin generics non ha alcun effetto collaterale nel codice esistente poiché al momento i generici non esistevano.
davidxxx,

2
Volevo solo dire che POTREBBE essere stato fatto come parola chiave. Solo perché sembra un identificatore, non significa che debba esserlo.
jaxad0127,

2
Direi che mainè ancora un identificatore migliore di java1234. Usarlo per un metodo "normale" sarebbe fuorviante, ma non avrei problemi a nominare una variabile main, se in realtà è l'elemento principale del mio metodo. java1234è semplicemente orribile, i nomi dovrebbero essere descrittivi ...
AJPerez,

1
"Riguardo alla domanda, il principale è un buon identificatore?" Dipende. Probabilmente non darei un'occhiata a una variabile chiamata mainse la funzione che stavo guardando ha fatto qualcosa con i dati principali dell'acqua. Vomiterei se mai vedessi java1234nel codice di produzione (e prego che non ci fossero altre 1233 variabili con il prefisso java).
jpmc26,

40

È un identificatore valido? Sì.

È un buon identificatore? Non se lo stai usando per qualcosa di diverso dal metodo che inizia al lancio di JVM.

È elencato un altro identificatore valido? Sì.

Le istruzioni del test hanno detto di scegliere la risposta migliore?


7
D'accordo: una scelta multipla come questa riguarda la scelta della risposta corretta "migliore" quando ce ne sono più. Tuttavia, ciò non rende questa una buona domanda a scelta multipla e penso che parlarne con l'insegnante sia la cosa giusta da fare.
Ombra

19
@Shadow Questo è un corso di programmazione. L'ambiguità su una domanda su qualcosa che è specificato con la grammatica matematica formale è intollerabile. Parlando rigorosamente contro quello standard (che è ciò che implica " valido "), entrambe le risposte sono ugualmente corrette. Posso immaginare molti più casi in cui mainè un identificatore tollerabile di quello che posso in quale java1234sarebbe. Si consideri, ad esempio, una base di codice che funziona con i dati di approvvigionamento idrico (rete idrica).
jpmc26,

5
D'altra parte, java1234 puzza nell'alto cielo come identificatore.
Giosuè,

4
"scegliere la risposta migliore" non significa "capire quando l'insegnante non sa di cosa stanno parlando e indovinare la risposta negativa a cui stanno pensando". main non è solo un identificatore valido , è un identificatore molto importante perché ogni applicazione Java ha un metodo principale e i metodi sono denominati con identificatori.
fluffysheap,

2
Trovo questa risposta molto supponente e vorrei poterla votare più di una volta. Sembra che tu stia cercando di schierarti dalla parte a tutti i costi e di non considerare il quadro più ampio. mainè un identificatore perfettamente preciso ovunque al di fuori dello stretto dominio della semplice applicazione Java. Potrebbe essere il nome di un campo in una classe che rappresenta un menu fisso. O una <main>sezione di un documento in un builder HTML. java1234d'altra parte, è terribile quanto gli identificatori ottengono.
toniedzwiedz,


29
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);
    }
}

7

Quell'insegnante ha commesso un piccolo errore nell'assumere che main non sia un identificatore valido o semplicemente nel formulare la domanda in modo errato. Forse intendeva dire "un buon identificatore".
Ma ignorare le argomentazioni dei tuoi figli e scoraggiare in tal modo il suo approccio scientifico di controllo della letteratura pertinente (specifica Java) ed eseguire un esperimento (scrivere un programma di esempio) è l' esatto contrario di ciò che un insegnante dovrebbe fare.


1
Come notato in altre risposte, mainè molto più spesso un identificatore "buono" di quanto non lo java1234sarebbe. Quindi anche lì, l'insegnante ha torto. ;)
jpmc26

5

Entrambi maine java123sono identificatori validi , main non è una parola chiave riservata, quindi è perfettamente accettabile da usare, per quanto riguarda il test dovresti aver ottenuto almeno un punto o mezzo punto.


5
  1. Dovrebbe essere una sola parola. Cioè gli spazi non sono ammessi.

    Esempio: il mangoprice è valido ma il prezzo del mango non è valido.

  2. Dovrebbe iniziare con una lettera (alfabeto) o un trattino basso o un simbolo $.

    Esempio: prezzo, _prezzo e $ prezzo sono identificatori validi.

  3. Non dovrebbe essere una parola chiave di Java poiché la parola chiave ha un significato speciale per il compilatore.

    Esempio: classe o vuoto ecc.

  4. Non dovrebbe iniziare con una cifra, ma la cifra può essere al centro o alla fine.

    Esempio: 5mangoescost non è valido e mango5cost e mangocost5 sono validi.

  5. La lunghezza di un identificatore in Java può essere di 65.535 caratteri e tutti sono significativi. Gli identificatori fanno distinzione tra maiuscole e minuscole. Sia il mango che il mango sono trattati in modo diverso. Può contenere tutte le lettere maiuscole o minuscole o una combinazione.

IDENTIFICATORE : sono nomi di classe, nomi di metodi, nomi di variabili ...

Poiché main non è una parola riservata e secondo la spiegazione sopra per definire un identificativo main è un identificatore valido e java1234 Le opzioni rimanenti non sono valide a causa della spiegazione sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.