Skip to content
metaClass — Runtime Modification
step 1/5

Reading — step 1 of 5

Learn

~1 min readMetaprogramming

Groovy lets you modify classes at runtime through metaClass. Add methods, replace methods, intercept calls — without subclassing.

String.metaClass.shout = { -> delegate.toUpperCase() + "!" }

"hello".shout()        // "HELLO!"
"world".shout()        // "WORLD!"

The delegate is the receiver — like this for the added method.

Per-instance metaclass:

def list = [1, 2, 3]
list.metaClass.greet = { -> "hi from list" }
list.greet()           // "hi from list"
[4, 5, 6].greet()      // MissingMethodException — only `list` has it

Replacing existing methods:

Integer.metaClass.toString = { -> "INT(" + delegate.toString() + ")" }
5.toString()           // "INT(5)" — affects EVERYONE

Use with extreme caution — modifying core classes affects every code path, including library code that didn't expect it.

methodMissing / propertyMissing — runtime catch-alls:

class DynamicProps {
    private Map data = [:]

    def methodMissing(String name, args) {
        if (name.startsWith("set")) {
            data[name.substring(3).toLowerCase()] = args[0]
            return null
        }
        if (name.startsWith("get")) {
            return data[name.substring(3).toLowerCase()]
        }
        throw new MissingMethodException(name, this.class, args)
    }
}

DynamicProps p = new DynamicProps()
p.setName("Ada")           // calls methodMissing
p.getName()                 // returns "Ada"

Similar to Ruby's method_missing. Used by ORM libraries and DSLs.

propertyMissing / setProperty intercept property access:

class Hash {
    Map data = [:]
    def propertyMissing(String name) { data[name] }
    def propertyMissing(String name, value) { data[name] = value }
}

Hash h = new Hash()
h.foo = "bar"
println h.foo               // "bar"

Performance hit: every missing-method invocation goes through reflection. Don't use in hot paths.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…