Well, "always" is a little wrong. The first time a message is passed and the bound method is called by the runtime is significantly slower (~4x slower than a virtual method call in C++). But then this message/method pair gets cached and for every subsequent call the cache is used.
Then there's some real neat trickery that is performed in objc_msgSend() ... after the method to "call" has been found the code directly jumps into that method without creating a new stack frame. (All needed arguments have been passed to objc_msgSend() and are already on the stack.) objc_msgSend() in essence is a trampoline.
So when sending a message to an object multiple times you only pay for the cache lookup - which is pretty fast by itself and a cached call is faster than a C++ virtual method call.
Performance Numbers: http://www.mikeash.com/pyblog/performance-comparisons-of-com...
More about objc_msgSend(): http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-buil...
Now I don't know enough about Java but I guess it isn't much more faster than that. So calling Obj-C slow may be a little too bold.