2015-07-14 3 views
1

Я не против, если я не понимаю, но я хочу знать, почему это происходит:Недействительные методы не могут вернуть значение метода void?

void something(String a) { 
    return hi(); 
} 
void hi() { 
    return; 
} 

Странным здесь является то, что hi() также имеет тип возвращаемого void. Я получаю ошибку синтаксиса в моем IDE:

Void methods cannot return a value 

Кроме того, код не компилируется:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Void methods cannot return a value 

    at Resources.setSystemProperties(Resources.java:33) 
    at Resources.main(Resources.java:49) 

Я бы ожидать, что это будет происходит:

hi() -> return nothing 

return [nothing] -> hi() is nothing 

Таким образом, в end, он ничего не возвращает, как и метод void.

Почему такое поведение происходит? И почему код не компилируется, когда возвращается результат метода void?

+4

Ответ: методы 'void' не могут вернуть значение *. Так просто. –

+0

И 'a.notify()' is 'void' ... Итак, почему я не могу вернуть результат? У меня есть три ответа, но ни один из них, похоже, не пытался ответить на мой вопрос. – Zizouz212

+0

Существует разница между 'return ;' и 'return;'. Наверное, это вас смущает. –

ответ

4

Это определяется в JLS 14.17:

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

  • метод, который объявлен возвращать значение
  • лямбда-выражение

Метод void не объявлен для возврата значения, поэтому оператор возврата с выражением (например, вызовом функции) не может произойти в таком методе.

Кроме того, вы не можете вернуть результат метода void из-за этого языка в JLS 15.12.3:

Если декларация времени компиляции является void, то вызов метода должен быть выражением верхнего уровня (то есть Выражение в выражении выражения или в ForInit или ForUpdate часть инструкции for) или возникает ошибка времени компиляции.

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

+0

Клянусь, из всех этих ответов ... Это действительно позволяет мне несколько понять поведение. Спасибо. – Zizouz212

2

Функция, объявленная как void, не может return ничего, точно так же, как ошибка говорит. Ваше предположение о том, что a.notify() возвращает что-либо, является ложным, потому что a.notify() также ничего не может вернуть (поскольку он недействителен).

+0

'a.notify()' является методом 'void'. Я никогда не говорил, что он что-то возвращает. – Zizouz212

2

Потому что так работает язык. Вы не можете использовать ключевое слово return для возврата значения в метод, у которого есть возвращаемый тип void. void is not a real value that can be passed around:

Класс Void является неинтересным классом-заполнителем для ссылки на объект класса, представляющий ключевое слово void.

Адрес an article by James Iry comparing void in Java with Unit in Scala. (В отличие от пустоты, блок представляет собой фактическое значение, которое может быть возвращено.) Он демонстрирует есть преимущества, имеющие тип блока вместо пустоты:

Java, C++ и C# программисты решают эту проблему все время. Один из распространенных вариантов заключается в том, чтобы не использовать функцию, но какая-то другая концепция, такая как «Действие», означает функцию, которая принимает строку, выполняет побочный эффект и не возвращает ничего полезного. Затем вы по существу дублируете «карту» во что-то, называемое «foreach», которое ожидает Action и возвращает void. Вероятно, это имеет смысл в этом случае, поскольку список ссылок на бессмысленное значение, возможно, является глупым, но это также означает большое дублирование кода, если такое программирование более высокого порядка является общим. Например, вы не можете написать только одну функцию компоновки, которая создает функцию из двух других функций, вам также нужно написать compose, который принимает действие и функцию для создания действия.

+0

@Codebender: правый, фиксированный. –

+0

'a.notify()' был просто использован как пример метода void, просто потому, что я не мог думать о каких-либо других. – Zizouz212

+0

@ Zizouz212: понял, это просто очень плохой пример. вы можете сделать другой метод с возвращаемым типом void. –

0

Компилятор Java не будет углубляться в глубину. Когда он видит ключевое слово return с некоторым значением, следующим в функции void, он будет генерировать ошибку компиляции. Он запрограммирован так. Так просто.

+0

Я могу поместить простой «return;» в мой код ... В этом нет ошибки – Zizouz212

0
return statements simply cannot be used with `Void` as it's Return type. 

Вы не можете изменить языковые правила!

Смежные вопросы