General background info:
The hardware part of any microprocessor only knows it needs to successively execute every instruction starting from a memory address -- it doesn't even know at which memory address to stop executing instructions.
Assembly language is a very thin converter from "commands" to "binary microinstructions". The list of "commands" does not include control flow statements at all all you have is jump instructions (simple jumps or conditional jumps), that's it (okay, there is an instruction for unconditional endless loops and for conditional loops).
Because of this the control flow statements which are available in higher languages such as C are implemented using these jump instructions because there is no other way to implement them. As it so happens goto
in C is compiled into binary instructions as just a simple unconditional jump instruction.
Java & JVM rationale:
Many different hardware architectures have different standards/formats for "binary microinstructions" and different sets of instructions. The JVM has its own standard and its own set of instructions.
This allows the Java Compiler to always output the same instructions no matter on what hardware architecture the executable will be run; it's the JVM's job to translate an instruction from its own standard into the current machine's standard.
So in essence the JVM bytecode is an "assembly language" for "the java virtual machine". Which means it doesn't have control flow instructions. It has unconditional jump instructions (which happen to be named goto
).
break
and continue
at the lowest level happen to be implemented as a jump
(or goto
). The point of the matter is that if you use a higher level language you would want to avoid using goto
even if it's available (like in C), and would use the more readable control structures.
There are some special cases (in C for ex.) when even programmers who respect all of the "best coding practices" would use a goto
for example coroutine implementations.
Some other examples of sacrificing the coding standards for better or more reliable performance is when Kernel developers have architecture specific assembly code (C allows you to write assembly instructions).