Returning a value from function

The JVM uses a value stack to hold values, and the stack is shared across all method calls on that thread. Normally, when a non-void method returns, the return value is pushed on the stack, and the caller pops it off the stack and either uses it or discards it.


JLS 14.17 The return Statement

[...] A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it.

[...] A return statement with an Expression attempts to transfer control to the invoker of the method that contains it; the value of the Expression becomes the value of the method invocation.

[...] It can be seen, then, that a return statement always completes abruptly.

The abrupt completion does mean that any following statements will not be executed, and this can in fact lead to compile-time error in some cases (JLS 14.21 Unreachable Statements)

void unreachable() {
   return;
   System.out.println("Bye!"); // DOESN'T COMPILE! Unreachable code!
}

Continuing on...

The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements [...] then any finally clauses [...] will be executed [...] Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.

This means that the following function will return -1 instead of 0.

int tryReturn() {
   try {
      return 0;
   } finally {
      return -1;
   }
}

In the absence of try-finally, though, the control will be immediately transferred, and the Expression value, if any, will be passed on to the caller.