Подтвердить что ты не робот

Почему я не могу явным образом вернуть void из метода?

void run() {
    ...
    if (done) return cancel();
    ...
}

где cancel() return void. Это не скомпилируется... и я могу понять, почему. Но если я хочу вернуть пустоту из пустоты, почему бы и нет? Вместо этого я в итоге пишу что-то вроде этого:

if (done) {
    cancel();
    return;
}

Я не ищу предложения в стиле кода, я хочу знать, почему Java явно запрещает возврат этого типа. Любая информация оценивается, спасибо.

4b9b3361

Ответ 1

Оператор return с выражением возвращает значение этого выражения. Тип cancel() - это выражение void - оно не имеет значения.

Логически вы хотите выполнить cancel(), а затем вернуться - так, что вы должны сказать. Два действия (вызов cancel(), а затем возврат) логически различны.

Теперь Java может иметь своего рода "unit" тип вместо void - но это повлияет скорее на большее, чем просто возвращаемые значения.

Ответ 2

Это интересный вопрос. Поскольку java применяет тип возвращаемого значения (void - тип возврата), ваше первое утверждение, по-видимому, имеет смысл. Я бы принял это только за конвенцию. Поскольку void является заполнителем, а не объектом, вероятно, было решено оставить его для согласованности языка или простоты компилятора.

От JLS

Оператор return без выражения должен содержаться в теле метода, объявленного с использованием ключевого слова void, а не для возврата какого-либо значения (§8.4) или в тело конструктора (§8.8).

далее

Чтобы быть точным, оператор return без Expression всегда завершается внезапно, причина - возвращение без значения

Ответ 3

Мне нравится писать:

void v=(void)1; 
return (v);

Итак, я думаю, что void не является type в Java.

В С++ return cancel(); является законным.

Как программист на С++, знакомый с Java, ответ таков: многие вещи не поддерживаются в синтаксисе Java. Возможно, для простоты или удобочитаемости.

Примечание. Объявление void f() похоже на объявление procedure f() в pascal, и процедура не может вернуть какое-либо значение, такое как функции, поэтому мы должны вызывать их в отдельном выражении.

Ответ 4

void не является типом. Однако если вы используете тип void вместо ключевого слова void, ваш код будет работать, но: вам придется вручную return null во всех точках выхода из вашего метода.

Ответ 5

Потому что вы не возвращаете void. void не является значением, поэтому его нельзя вернуть.

Ответ 6

Это тавтология. Значение void определяет, что метод не имеет возвращаемого значения. Поэтому, как вы можете "вернуть пустоту", когда пустота не возвращается вообще?

Ответ 7

Короткий ответ

Оператор return cancel() должен возвращать допустимое значение, но объявление метода void run() объявляет, что run() не возвращает значение; следовательно, return cancel() в run() является ошибкой. Оператор return (без выражения) пытается передать управление вызывающему и используется, когда тип возвращаемого метода void; следовательно, не является ошибкой.

Длинный ответ

JLS The *return* Statement section утверждает

Оператор return без выражения Expression пытается передать управление вызывающему методу или конструктору, который его содержит. [...] Оператор return с выражением должен содержаться в объявлении метода, объявленном для возврата значения (§8.4) или возникает ошибка времени компиляции. Выражение должно обозначать переменную или значение некоторого типа T, или возникает ошибка времени компиляции. Тип T должен быть присвоен (§5.2) объявленному типу результата метода или произошла ошибка времени компиляции.

Раздел JLS Method Return Type гласит:

Возвращаемый тип метода объявляет тип значения, возвращаемого методом, если он возвращает значение, или указывает, что метод недействителен. Объявление метода d1 с типом возврата R1 является возвращаемым типом-заменяемым для другого метода d2 с типом возврата R2, тогда и только тогда, когда выполняются следующие условия: [...] * Если R1 недействителен, тогда R2 является недействительным.

JLS Types, Values, and Variables глава, первый абзац гласит:

Язык программирования Java - это строго типизированный язык, что означает, что каждая переменная и каждое выражение имеют тип, который известен во время компиляции. Типы ограничивают значения, которые может удерживать переменная (§4.12), или что может выражать выражение, ограничивать операции, поддерживаемые этими значениями, и определять значение операций.

Раздел JLS The Kinds of Types and Values гласит:

В языке программирования Java существуют два типа типов: примитивные типы (§4.2) и ссылочные типы (§4.3). Существуют, соответственно, два типа значений данных, которые могут быть сохранены в переменных, переданы в качестве аргументов, возвращены методами и работают с: примитивными значениями (§4.2) и ссылочными значениями (§4.3).

Еще несколько цитат. Раздел JLS Expression Statements гласит:

В отличие от C и С++ язык программирования Java допускает использование только определенных форм выражений. Обратите внимание, что язык программирования Java не позволяет "cast to void" -void не является типом

Раздел JLS Method Body гласит:

Если метод объявлен недействительным, то его тело не должно содержать никакого оператора return (§14.17), имеющего выражение.

И, наконец, раздел JLS Method Declarations гласит:

Объявление метода либо указывает тип значения, возвращаемого методом, либо использует ключевое слово void, чтобы указать, что метод не возвращает значение.

Теперь, когда мы собираем все это вместе, мы можем вывести следующее:

  • Если оператор return содержит выражение, выражение должно оцениваться с допустимым значением.
  • Действительное значение выражения return должно быть примитивным типом или ссылочным типом.
  • void не является допустимым типом значения.
  • Метод, объявленный с возвращаемым типом void, не возвращает значения.
  • Метод void run() не возвращает значение.
  • В run(), return, без выражения, с радостью передаст управление вызывающему.
  • В run(), return some expression является ошибкой, потому что some expression должно быть допустимым значением, а run() не возвращает значение.

Ответ 8

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

void - это, строго говоря, отсутствие типа и, следовательно, отсутствие значения - поэтому нет смысла возвращать его, точно так же, как это не имеет смысла (и не допускается) объявить переменную void.

Ответ 9

Пустота не является реальным типом. Void является просто владельцем места, чтобы сделать синтаксис определения методов более последовательным. Это не инновация java; это наследуется от C.

Именно по этой причине компилятор не позволяет писать return cancel(), даже если метод cancel() равен void.

Ответ 10

void не является типом. void в определении метода просто заполнитель для ничего не возвращает.

Ответ 11

Интересная идея. Основной проблемой является спецификация языка, которая определяет оператор return как состоящий из return <expression>. Метод void не является выражением, поэтому конструкция не разрешена.

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

Ответ 12

Из JLS:

Оператор возврата без выражения должен содержаться в теле метод, который объявляется с использованием ключевого слова void, а не для возврата значение или в теле конструктора

...

Оператор return с выражением должен содержаться в методе объявление, объявленное для возврата значения или времени компиляции возникает ошибка. Выражение должно обозначать переменную или значение некоторого тип T или ошибка времени компиляции. Тип T должен быть назначен к объявленному типу результата метода или ошибке времени компиляции имеет место.

Ответ 13

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

Но, конечно, ничто из этого не объясняет ответ на ваш вопрос. Как вы указали, нет причин, по которым эта идиома не должна допускаться. Но также нет веских оснований для его разрешения. Так что он подбрасывает. Можно попытаться рационализировать, почему они сделали то, что сделали, но это, вероятно, было бы бессмысленным.

Ответ 14

Правильный способ справиться с этим:

void run() {
...
if (done) {
    cancel();
    return;
    }
...
}