Any method that mutates returns a copy, pretty easy to preserve immutability in OOP.
Why would you somehow pass objects around that are not "final"?
I mean the objects that get pinned here and there are specifically designed to serve as wrappers for some state, hence they encapsulate that state, and thus they are mutable. (For example a DB connection/manager object, a service registry, a cookie/localStorage repository.)
Where the immutability usually helps is with shuffling data around, parallel computing (concurrent access, no need to lock), etc.