Один из моих детей изучает Java в средней школе и на одном из тестов получил следующее:
Which of the following is a valid identifier in Java?
a.
123java
b.main
c.java1234
d.{abce
e.)whoot
Он ответил б и ошибся.
Я посмотрел на вопрос и утверждал, что mainявляется действительный идентификатор и что он должен был быть правильным.
Мы рассмотрели Java спецификация для идентификаторов, и это подтвердило эту точку зрения. Мы также написали пример программы с переменной main и методом. Он создал письменное опровержение, которое включало ссылку на документацию Java, тестовую программу, и учитель проигнорировал его и сказал, что ответ все еще неверен.
main - действительный идентификатор?
я думаю, это так. но вам действительно не следует использовать его в качестве имени переменной / метода (несмотря на очевидный случай), поэтому, если учитель пытается детализировать точку до дома, чтобы подумать - особенно в этом случае - о названиях методов, тогда я могу увидеть его / ее точка.
Действительно ли этот вопрос задает вопрос, правильно ли учитель вашего сына выполняет свою работу? Я вижу два действительных идентификатора Java. Итак, ответ - «b» А ТАКЖЕ «c». Итак, учитель прав. Или я что-то упускаю ?. Как это может быть ТАК вопрос? Судя о каком-то человеке, который даже не является частью сообщества ...
Это вопрос об учителях, а не о java.
Еще один из тех случаев, когда «обманули ваш собственный вопрос с подвохом»; Учителя действительно должны хотя бы взглянуть на спецификацию языка, прежде чем пытаться написать такой вопрос на экзамене.




main - допустимый идентификатор Java, и учитель ошибается.
Соответствующая документация находится в Спецификации языка Java, прямо здесь:
Глава 3. «Лексическая структура», раздел 3.8. «Идентификаторы»:
https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8
Он говорит:
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter... An identifier cannot have the same spelling (Unicode character sequence) as a keyword (§3.9), boolean literal (§3.10.3), or the null literal (§3.10.7), or a compile-time error occurs.
Это означает, что вы можете доказать, что это действительный идентификатор:
Не могли бы вы процитировать и изложить это более подробно?
нет, потому что это целый раздел. Если учитель думает, что в этом разделе делается какое-то исключение для «основного», именно учитель должен показать, где это сказано.
main вполне допустим, потому что он, из документов:
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 identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:
JavaLetter {JavaLetterOrDigit}
JavaLetter:
any Unicode character that is a "Java letter"
JavaLetterOrDigit:
any Unicode character that is a "Java letter-or-digit"
Последовательность символов main соответствует приведенному выше описанию и отсутствует в список ключевых слов в Разделе 3.9.
(Последовательность символов java1234 также является идентификатором по тем же причинам.)
@Clockwork Вопрос был сформулирован так, что только один вариант мог быть правильным. Однако оба варианта бб> и c удовлетворяли условию вопроса, что несовместимо с подразумеваемым выбором. Это оставило ребенка ОП выбирать, какой правильный ответ будет единственным, который учитель посчитал правильным.
@rgettman Я прочитал "Который из перечисленных..." как разрешающий более одного раза выбор, на который "б и в" будет правильным ответом.
@TripeHound "- действительный идентификатор" - единственное число и требует ровно 1 ответа. Сравните это с «действительными идентификаторами»
Можно было бы сделать и класс main;)
Как утверждают другие ответы
main - действительный идентификатор Java, а также java1234.
Я предполагаю, что это сбивает с толку тот факт, что метод main(String[]) часто используется JVM1 в качестве точки входа. Однако это не означает, что сам токен main нельзя использовать в качестве идентификатора 2.
Об этом говорится в спецификации, и следующие декларации также действительны:
Поле:
private int main;
Локальная переменная:
String main = "";
Метод:
void main() { ... }
Класс или интерфейс (хотя имя класса или интерфейса, начинающееся с нижнего регистра, не рекомендуется):
class main { ... }
Пакет:
package main;
1: As noted in the comments, the JVM specification itself does not mandate any particular method as entry point, but the widely used java tool often uses such a method as entry point.
2: I would generally avoid creating a main method other than main(String[]).
main не является точкой входа для JVM. Это точка входа, которую инструмент java использует для запуска приложений. Другие инструменты (например, контейнеры сервлетов) используют другие точки входа.
что еще более иронично, потому что даже в главном "контексте точки входа" УЖЕ ЕСТЬ действительный идентификатор. Таким образом, даже случай, который вы могли бы возразить, на самом деле доказывает, что OP прав.
@ T.J. Crowder Спасибо, я включил это в ответ.
Объявление 2: И я обычно избегает создания основного метода, отличного от public static void main(String[]). ;)
@Hobbamok Вы, кажется, не понимаете основных концепций Java, что, вероятно, объясняет, почему вы преподаете его в школе, а не практикуете - ответ, который приходит на ум
Инструмент java не требует метода main(String[]), если основной класс расширяет javafx.application.Application.
Как main нельзя использовать в качестве идентификатора, в то время как он используется в качестве идентификатора для объявления «основного» метода?
Для такой классической идиомы:
public class Foo{
public static void main(String[] args){
}
}
main не является ключевым словом и, вероятно, никогда не будет ключевым словом в Java по очевидным причинам ретро-совместимости.
По поводу вопроса, main - хороший идентификатор?
Во-первых: допустимый для компилятора не обязательно означает хороший.
Например, предлагаемая опция java1234 также является допустимым идентификатором, но этого действительно следует избегать.
main имеет очень конкретное и важное значение: он используется как метод точки входа для классов и jar-файлов, выполняемых из командной строки 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)._, $ или любыми неожиданными / бессмысленными символами, которые противоречат соглашениям об общих именах (4).Следует отметить, что main может быть ключевым словом, которое можно использовать только как имя для статического метода с соответствующей подписью (или чем-то еще). Обратите внимание, что вызовы суперкласса используют super таким образом, чтобы он выглядел как идентификатор: super(foo); и super.foo, но super ЯВЛЯЕТСЯ ключевым словом (и до того, как были добавлены дженерики, это был единственный способ его использования (насколько я помню)).
@ jaxad0127 Интересный момент, но я не полностью согласен. На самом деле это не так, и в будущем, вероятно, не может быть по причинам совместимости. Если вы определили main как ключевое слово в новой версии java, это означает, что любой код, который использует main как имя метода (или любые имена членов), больше не будет компилироваться. Использование super в дженериках не имеет побочных эффектов в существующем коде, поскольку в то время дженериков не существовало.
Я просто имел в виду, что это МОЖНО сделать как ключевое слово. Просто потому, что это похоже на идентификатор, не означает, что так должно быть.
@ jaxad0127 Не углубляясь слишком глубоко в JLS и для двух упомянутых вами случаев, я думаю, можно сказать, что super - это особое выражение: оно представляет собой ссылку на объект Class, который будет использоваться с конструктором объекта и его членами.
Я бы сказал, что main по-прежнему лучший идентификатор, чем java1234. Использование его для «обычного» метода было бы ошибочным, но у меня не возникло бы проблем с присвоением имени переменной main, если это действительно главное в моем методе. java1234 просто ужасен, названия должны быть описательными ...
"Насчет вопроса, является ли main хорошим идентификатором?" Это зависит. Я бы, наверное, и глазом не взглянул на переменную с именем main, если бы функция, на которую я смотрел, что-то делала с данными водопровода. Меня бы вырвало, если бы я Когда-либо увидел java1234 в производственном коде (и молюсь, чтобы не было 1233 других переменных с префиксом java).
@ jaxad0127 main можно было бы определить как ключевое слово, он все равно мог бы стать ключевым словом, точно так же, как _ перестал быть законным идентификатором, однако это не так, и это было осознанное решение. Дизайнеры Java решили, что, например, goto и const являются ключевыми словами, чтобы предотвратить их использование в качестве вводящих в заблуждение идентификаторов, но main не требует такой специальной обработки.
@AJPerez Полностью согласен. Но хорошо оба плохие. Вы могли заметить, что я добавил main в качестве имени переменной, но я не цитировал его в вещах, которые нам не нужны (не об опасности). Но я уберу его для единообразия.
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);
}
}
Это отлично компилируется на 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
Можно ли добавить еще один метод static main с другими параметрами?
@ jpmc26 Попробуйте и расскажите, как все прошло. :)
Ну это много электросети
@MCEmperor Да, это мой аргумент главный в пользу моего ответа. ;)
Вы забыли добавить package main;!
Это действительный идентификатор? да.
Это хороший идентификатор? Нет, если вы используете его для чего-то другого, кроме метода, который запускается при запуске JVM.
Есть ли в списке другой действительный идентификатор? да.
В инструкциях к тесту говорилось, что нужно выбрать лучший ответ?
Согласовано - подобный множественный выбор касается выбора «наилучшего» правильного ответа, когда их несколько. Однако это не делает этот вопрос хорошим с несколькими вариантами ответов, и я думаю, что поговорить об этом с учителем - это правильно.
@Shadow Это курс программирования. Двусмысленность в вопросе о том, что определяется формальной математической грамматикой, недопустима. Если говорить строго против этого стандарта (что подразумевается под «действительный»), оба ответа одинаково верны. Я могу представить гораздо больше случаев, в которых main является допустимым идентификатором, чем я могу, когда java1234 был бы. Рассмотрим, например, кодовую базу, работающую с данными о водоснабжении (водопровод).
@Holger Я ничего не говорю. Обратите внимание на кавычки вокруг слова лучше. Но очевидно, что этот инструктор так думает.
@ jpmc26, цитирую самого себя, «это не делает его хорошим вопросом с несколькими вариантами ответов, и я думаю, что поговорить об этом с учителем - это правильно». Пожалуйста, перестаньте притворяться, будто я согласен с тем, что здесь произошло.
С другой стороны, java1234 воняет до небес как идентификатор.
«выбрать лучший ответ» не означает «выяснить, когда учитель не знает, о чем они говорят, и угадать плохой ответ, о котором они думают». main - это не только идентификатор действительный, это идентификатор очень важно, потому что каждое приложение Java имеет основной метод, а методы именуются с идентификаторами.
Я считаю этот ответ весьма самоуверенным и хотел бы проголосовать против него более одного раза. Похоже, вы пытаетесь встать на чью-то сторону любой ценой, не учитывая более широкую картину. main - идеальный идентификатор для любого места за пределами узкой области простого Java-приложения. Это может быть имя поля в классе, представляющем заданное меню. Или раздел документа <main> в построителе HTML. java1234, с другой стороны, настолько же ужасен, насколько и идентификаторы.
Я бросил на это все, что мог, и, похоже, это сработало. Я бы сказал, что 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;
}
}
}
Мне это нравится. Попробуйте 'grep -o main main.java | туалет -l '
Этот код чем-то напоминает мне язык программирования "ook" ^^ Почти каждое слово в этом коде - "main" ...
Я чувствую, что поддержал это.
@GeroldBroser Это чище, но не является строго необходимым: пробелы между токенами во многих случаях необязательны, они требуются только тогда, когда в противном случае было бы допустимо объединение двух последующих токенов.
И main, и java123 являются идентификаторами действительный, main не является зарезервированным ключевым словом, поэтому его вполне можно использовать, что касается теста, вы должны получить как минимум балл или пол-балла.
Этот учитель допустил небольшую ошибку, предположив, что главный не является допустимым идентификатором, или просто неправильно сформулировал вопрос. Возможно, он хотел сказать «хороший идентификатор».
Но игнорирование аргументов ваших сыновей и тем самым препятствование его научному подходу к проверке соответствующей литературы (спецификация Java) и проведению эксперимента (написание примера программы) - это прямо противоположное того, что должен делать учитель.
Как отмечалось в других ответах, main гораздо чаще является «хорошим» идентификатором, чем java1234. Так что даже здесь учитель ошибается. ;)
Должно быть одно слово. То есть пробелы не допускаются.
Пример: цена на манго действительна, но цена на манго недействительна.
Должен начинаться с буквы (алфавита), подчеркивания или символа $.
Пример: цена, _price и $ price являются допустимыми идентификаторами.
Не должно быть ключевым словом Java, поскольку ключевое слово имеет особое значение для компилятора.
Пример: class или void и т. д.
Не должно начинаться с цифры, но цифра может быть в середине или в конце.
Пример: 5mangoescost недействителен, а mango5cost и mangocost5 действительны.
Длина идентификатора в Java может составлять 65 535 символов, и все они значимы. Идентификаторы чувствительны к регистру. То есть и к манго, и к манго относятся по-разному. Может содержать все буквы в верхнем или нижнем регистре или их сочетание.
ИДЕНТИФИКАТОР: это имена классов, имена методов, имена переменных ...
Поскольку main не является зарезервированным словом, и в соответствии с приведенным выше объяснением для определения идентификаторов main - действительный идентификатор и java1234 также. Остальные параметры не действительны из-за вышеприведенного объяснения.
Мне всегда грустно видеть учителя настолько неуверенным в себе, что он / она боится узнать что-то новое и признать ошибку.