I mean, I very much disagree on this being "complicated and inferior". But none of these techniques are substitutes for each other. Like the article said, there are a lot of lead bullets, no silver ones. You absolutely should deploy whatever techniques you can. All I was saying was that I think this one, on its own, would handle a larger set of cases than some of the other (run-time) ones listed.
But one big reason I suggested this technique is that you want the object to keep protection on the String while having it look and feel as much like the underlying contents as possible, so that the final unsealing can occur as little (& as late) as possible. The more warts you put around your secret, the less usable it will be. You thought you made the Secret "single-use", but what you really did was to just encourage someone to keep the unsealed String around and reuse that, because you gave them a Secret type and they needed a String type. And now you have no way to detect if they accidentally log it, or throw an exception with some local variable containing it. Whereas this technique would still immediately catch any leakage in those cases.
Again: this technique is a supplement, not a substitute. You absolutely should still add static checks where you can. Have your Secret type too. The point here is that your Secret.unseal() method can still return a String that is useful for callers while offering you some protection on the value, instead of instantly going from protected->unprotected and exposing the contents with zero protection.