Является ли main допустимым идентификатором Java?

один из моих детей принимает Java в средней школе и имел это на одном из своих тестов:

какой из следующих является допустимым идентификатором в Java?

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

он ответил b и ошибся.

Я посмотрел на вопрос и утверждал, что main и a действительно и что это должно было быть правильно.

мы взглянули на Java spec для идентификаторов, и это усилило эту точку. Мы также написали пример программы с переменной main, а также способ. Он создал письменное опровержение, которое включало ссылку на документацию Java, тестовую программу, и учитель проигнорировал ее и сказал, что ответ по-прежнему неверен.

и main допустимым идентификатором?

14 ответов


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

это компилируется, и при выполнении, выдает этот вывод:

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

последовательность символов main - это идентификатор, а не ключевое слово или зарезервированное слово.

на соответствующий раздел JLS составляет 3,8:

An идентификатор неограниченный-длина последовательности буквы Java и цифры Java, первый из которых должен быть Java letter.

идентификатор:

IdentifierChars, но не Ключевое слово или BooleanLiteral или NullLiteral

IdentifierChars:

JavaLetter {JavaLetterOrDigit}

JavaLetter:

любой символ Юникода, который является "буквой Java"

JavaLetterOrDigit:

любой символ Юникода, который является "буквой или цифрой Java"

последовательность символов main подходит выше описания и нет в список ключевых слов в разделе 3.9.

(последовательность символов java1234 также является идентификатором, по тем же причинам.)


main является допустимым идентификатором java, и учитель ошибается.

соответствующая документация находится в спецификации языка Java, прямо здесь:

Глава 3. "Лексическая структура", раздел 3.8. "Идентификаторы":

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

Он говорит:

идентификатор-это последовательность букв и цифр Java неограниченной длины, первая из которых это должно быть письмо Java... Идентификатор не может иметь такое же написание (последовательность символов Юникода), как ключевое слово (§3.9), логический литерал (§3.10.3) или нулевой литерал (§3.10.7), или возникает ошибка времени компиляции.

это означает, что вы можете доказать, что это допустимый идентификатор, используя его в качестве идентификатора и наблюдая, что ошибка времени компиляции не возникает.


как другие ответы состояние

main является допустимым идентификатором Java, а также java1234.

Я думаю, что путаница происходит от того, что main(String[]) метод часто используется в качестве точки входа JVM1. Однако это не означает, что токен main себя нельзя использовать как идентификатор2.

спецификации говорят так, и следующие объявления также действительно:

  • поле:

    private int main;
    
  • локальная переменная:

    String main = "";
    
  • методика:

    private void main() { ... }
    
  • класс (хотя имя класса, начинающееся с нижнего регистра, не рекомендуется):

    public class main { ... }
    
  • пакет:

    package main;
    

1: Как отмечено в комментариях, сама спецификация JVM не мандат любого конкретного метода в качестве точки входа, но широко используется часто использует такой метод, как точка входа.
2: я бы вообще избегал создания основного метода, отличного от main(String[]).


это прекрасно компилируется на 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);
    }
}

...а при выполнении выдает вывод:

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

как main не может использоваться в качестве идентификатора, пока он используется в качестве идентификатора для объявления метода "main"?

для такой классической идиомы:

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

main не является ключевым словом, и это, вероятно, никогда не будет ключевым словом в Java по очевидным причинам ретро-совместимости.


о вопросе, есть main хорошая идентификатор ?

First: valid для компилятора не означает обязательно хорошо.
Для пример java1234 опция, которая предлагается также является допустимым идентификатором, но этого действительно следует избегать.

main имеет очень особое и важное значение : она используется в качестве метода точки входа классов и банок, выполненных java командная строка.
Используя main для имени метода, которое не заполняет критерии, используемые java командная строка будет просто вводить в заблуждение при использовании ее в качестве имени переменной или имени класса может сделать чувство.
Например, определение класса, представляющего точку входа приложения как Main класс приложения приемлем и поэтому использует его в качестве имени переменной, например:

public class Main {

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

}

в общем случае в Java несколько символов или "слов" считаются допустимыми идентификаторами для компилятора, но настоятельно не рекомендуется использовать в клиентском коде (но сгенерированный код может сделать это : например, вложенные классы) как не читаемые и / или действительно вводящий в заблуждение.

например, это может быть допустимо для компилятора:

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

но мы не хотим :

  • на имя Object наш класс, как это определено в java.lang(1).
  • чтобы назвать метод main() если не заполняет критерии, которые будут использоваться java командная строка (2).
  • перегрузить Object.toString() метод (3).
  • чтобы назвать наши переменные с _, $ или любой удивительно/unmeaningful символы, которые идут против общего соглашения об именовании (4).

это действительный идентификатор? Да.

Это хороший идентификатор? Нет, если вы используете его для чего-либо, кроме метода, который начинается при запуске JVM.

указан ли другой допустимый идентификатор? Да.

в инструкциях по тестированию сказано выбрать лучший ответ?


Я бросил в него все, что мог, и он, похоже, работает. Я бы сказал, что main-действительный идентификатор.

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

main совершенно справедливо, потому что это,документы:

  1. представляет собой "последовательность букв Java и цифр Java, первая из которых является буквой Java"
  2. - это не ключевое слово
  3. - это не логический литерал т. е. "true"или " false"
  4. не нулевой литерал

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

этот учитель допустил небольшую ошибку в любом предположении main не является допустимым идентификатором или просто формулирует вопрос неправильно. Возможно, он хотел сказать "хороший идентификатор".
Но игнорирование аргументов ваших сыновей и тем самым обескураживание его научного подхода к проверке соответствующей литературы (спецификация Java) и проведению эксперимента (написание примерной программы) - это противоположность о том, что должен делать учитель.


и main и java123 are действительный идентификаторы, main не является зарезервированным ключевым словом, поэтому вполне приемлемо использовать, поскольку тест идет, вы должны были получить точку или половину точки, по крайней мере.


  1. должно быть одно слово. То есть пробелы не допускаются.

    пример: mangoprice действителен, но цена манго недействительна.

  2. следует начинать с буквы (алфавита) или подчеркивания или символа$.

    пример: price, _price и $price являются допустимыми идентификаторами.

  3. не должно быть ключевым словом Java, поскольку ключевое слово несет особое значение для компилятор.

    пример: класс или void и т. д.

  4. Не следует начинать с цифры, но цифра может быть посередине или в конце.

    пример: 5mangoescost недопустим, а mango5cost и mangocost5 допустимы.

  5. длина идентификатора в Java может быть 65535 символов и все значительные. Идентификаторы чувствительны к регистру. То есть и манго, и манго трактуются по-разному. Мочь содержит все заглавные буквы или строчные буквы или смесь.

идентификатор: это имена классов, имена методов, имена переменных ...

as main не является зарезервированным словом и в соответствии с приведенным выше объяснением для определения идентификатора main является допустимым идентификатором и java1234 также.Остальные варианты недействительны из-за приведенного выше объяснения.


вы можете использовать любое слово, которое не Ключевое слово, Boolean, Null или начинается с номера в качестве идентификатора, слово "main" является наиболее используемым идентификатором, но - в вашем случае - вы можете использовать java1234.


    option b and c boths are valid, because main is not a keyword or reserve word it's also valid.
   option a,d and e is invalid because you cant declare the identifiers with which have start with number or special character(except _ and $).
you can declare - abc_123,_abc,$abc
but can't declare like 123_abc,123_