В моем учебнике AP Computer Science указано, что метод add()
в интерфейсе List
всегда возвращает значение true
, но при вызове этого метода его тип возврата не требуется.
Я предполагаю, что значение просто выброшено, потому что в этой ситуации оно не привязано ни к чему. Это вызывает вопрос, в каких ситуациях ценности "отбрасываются". Например, следующее не компилируется.
Почему второй фрагмент не компилируется, когда он по существу оставляет то же значение, что и первый фрагмент? (list.add()
возвращает true
, (1 < 2)
дает true
).
Возвращаемые значения можно игнорировать. Неполные выражения все еще неполны. Вы можете назначить его переменной (и никогда не ссылаться на нее снова) - это "выбросит" значение (eclipse предупредит вас, но это не ошибка) -
// This is legal, note that a is never referenced after assignment.
public static void main(String[] args) {
boolean a = (1 < 2);
}
Блоки кода могут содержать утверждения, но не сами выражения. Раздел 14.2 JLS определяет, что может быть внутри блоков, а выражения сами по себе недопустимы.
Блок:
- {[BlockStatements]}
BlockStatements:
- BlockStatement {BlockStatement}
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
утверждение
(акцент мой)
Одним из возможных операторов является вызов метода, поэтому вызов метода, возвращающее значение которого не назначается, является выражением, но само выражение не является выражением.
Раздел 14.5 JLS определяет оператор как одно из следующего:
Заявление: - StatementWithoutTrailingSubstatement
LabeledStatement
IfThenStatement
IfThenElseStatement
WhileStatement
ForStatement
StatementNoShortIf:
StatementWithoutTrailingSubstatement
LabeledStatementNoShortIf
IfThenElseStatementNoShortIf
WhileStatementNoShortIf
ForStatementNoShortIf
StatementWithoutTrailingSubstatement:
блок
EmptyStatement
ExpressionStatement
AssertStatement
SwitchStatement
DoStatement
BreakStatement
ContinueStatement
ReturnStatement
SynchronizedStatement
ThrowStatement
нетерминала ИнструкцияTry
(акцент мой)
Раздел 14.8 JLS определяет выражение "выражение":
ExpressionStatement:
Выражение выражения;
StatementExpression:
присваивание
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression
(акцент мой)
Выражение само по себе не является выражением выражения или выражением.
РЕДАКТИРОВАНИЕ
Вызов метода, который возвращает значение, имеет значение, потому что это не просто возвращаемое значение. В данном примере метод добавляет элемент в коллекцию и возвращает ссылку, поэтому ее можно обрабатывать.
Второй пример - это ошибка, потому что без присвоения ее результата переменной ее бессмысленно. его даже хуже, чем dead code
.
Теоретически второе утверждение не могло быть ошибкой, но почему же кто-то захотел бы написать такие "заявления"?
Выражения, которые буквально дают что-либо, являются всего лишь потребителем процессора, ошибкой и не должны использоваться ни в какой программный период.
(1<2);
может быть легко переведено на байт-код и, кроме того, на процессорные команды, такие как
PUSH EAX;
PUSH EBX;
PUSHF;
MOV EAX, 1;
MOV EBX, 2;
CMP EAX,EBX;
POPF;
POP EBX;
POP EAX;
или даже проще
PUSHF;
CMP 1,2;
POPF;
Единственное, что изменит код выше, - это увеличение регистра, указывающего на следующий код в памяти (и несколько других). Так почему бы кто-нибудь выполнить такие строки?
Сгенерированная ошибка компиляции связана с java-грамматиком. Java-грамматик утверждает, что тело java-функции состоит из последовательности операторов. В соответствии с этим выражением грамматики могут быть любые присваивания, вызов метода, условная структура, циклы и т.д. Но <b - это логическое выражение, которое нельзя считать оператором. Таким образом, речь идет о различии между выражением и выражением, а не сбрасыванием значений.
true
.