I was reading through design philosophy of java and this line struck me: "The VM checks whether the signature of the Java code is valid and would refuse to interpret if any change of the code is detected." how does the vm ensure that bytecode hasn't been changed?
The Java byte-code class file format captures method signatures both in the caller and in the callee (i.e. the method definition).
Thus, it can compare the two signatures, and if a mismatch is detected, then one was compiled with a different expectation of the other, which is no longer valid.
Other features of the byte-code format ensure that the signature being mentioned is also being, at least syntactically, correctly used. For example, that the right number of parameters are being passed by the caller, and that the callee's implementation expects exactly those parameters and no more. (Of course this doesn't prevent all possible bugs, just certain classes of issues.)
This property of the byte-code format is absent (or optional) in some other binary executable formats.
However, some languages provide different mechanisms. For example, C++ has used Name Mangling to help ensure the right method with the right signature is called; this is a form of capturing the method signature both at the call site as well as at the method definition.
It utilizes code signing certificates.
Or simplified there's essentially a checksum added to the file together with some more information on who generated said checksum. It's a bit more complicated than that to prevent or at least detect manipulation (e.g. replacing the checksum), but I guess you can look up most of that online or in documentation now that you know the term.