Method overloading in Java occurs at compile-time with multiple methods sharing the same name but differing in parameter types or counts, while method overriding happens at runtime, allowing a subclass to provide a specific implementation of a method in its superclass. Overloading enhances performance compared to overriding, as overridden methods execute during playback. Additionally, private and final methods cannot be overridden, allowing for multiple such methods in a class but restricting access from subclassing.