With name space management, privileges are established when the program is linked. If those privileges are too strong, there is no way to revoke them later -- once a class name is resolved into an implementation, there is no way to unlink it.
In contrast, capabilities have very desirable properties. If a program wishes to discard a capability, it only needs to discard its reference to the capability. Likewise, if a method only needs a subset of the program's capabilities, the appropriate subset of capabilities may be passed as arguments to the method, and it will have no way of seeing any others. If a capability needs to be passed through the system and then back to the program through a call-back (a common paradigm in GUI applications), the capability can be wrapped in another Java object with non-public access methods. Java's package scoping mechanism provides the necessary semantics to prevent the intermediate code from using the capability.
Stack introspection provides an interesting middle-ground. A program which enables a privilege and calls a method is implicitly passing a capability to that method. If a privilege is not enabled, the corresponding target cannot be used. This allows straightforward auditing of system code to verify that privileges are enabled only for a limited time and used safely. If a call path does not cross a method that enables its privileges, then that call path cannot possibly use the privilege by accident. Also, there is a disablePrivilege() method which can explicitly remove a privilege before calling into untrusted code. Most importantly, when the method which enabled a privilege exits, the privilege disappears with it. This limits the lifetime of a privilege.