Package groovy.lang

# Class ExpandoMetaClass

java.lang.Object
groovy.lang.MetaClassImpl
groovy.lang.ExpandoMetaClass

All Implemented Interfaces:
  `GroovyObject`, `MetaClass`, `MetaObjectProtocol`, `MutableMetaClass`

public class ExpandoMetaClass extends MetaClassImpl implements GroovyObject
ExpandoMetaClass is a MetaClass that behaves like an Expando, allowing the addition or replacement of methods, properties and constructors on the fly.

Some examples of usage:

     // defines or replaces instance method:
     metaClass.myMethod = { args -> }

     // defines a new instance method
     metaClass.myMethod << { args -> }

     // creates multiple overloaded methods of the same name
     metaClass.myMethod << { String s -> } << { Integer i -> }

     // defines or replaces a static method with the 'static' qualifier
     metaClass.'static'.myMethod = { args ->  }

     // defines a new static method with the 'static' qualifier
     metaClass.'static'.myMethod << { args ->  }

     // defines a new constructor
     metaClass.constructor << { String arg -> }

     // defines or replaces a constructor
     metaClass.constructor = { String arg -> }

     // defines a new property with an initial value of "blah"
     metaClass.myProperty = "blah"

ExpandoMetaClass also supports a DSL/builder like notation to combine multiple definitions together. So instead of this:

     Number.metaClass.multiply = { Amount amount -> amount.times(delegate) }
     Number.metaClass.div =      { Amount amount -> amount.inverse().times(delegate) }

You can also now do this:

     Number.metaClass {
         multiply { Amount amount -> amount.times(delegate) }
         div      { Amount amount -> amount.inverse().times(delegate) }
     }

ExpandoMetaClass also supports runtime mixins. While `@Mixin` allows you to mix in new behavior to classes you own and are designing, you can not easily mixin anything to types you didn't own, e.g. from third party libraries or from JDK library classes. Runtime mixins let you add a mixin on any type at runtime.

     interface Vehicle {
         String getName()
     }

     // Category annotation style
     @Category(Vehicle) class FlyingAbility {
         def fly() { "I'm the ${name} and I fly!" }
     }

     // traditional category style
     class DivingAbility {
         static dive(Vehicle self) { "I'm the ${self.name} and I dive!" }
     }

     // provided by a third-party, so can't augment using Mixin annotation
     class JamesBondVehicle implements Vehicle {
         String getName() { "James Bond's vehicle" }
     }

     // Can be added via metaClass, e.g.:
     // JamesBondVehicle.metaClass.mixin DivingAbility, FlyingAbility
     // Or using shorthand through DGM method on Class
     JamesBondVehicle.mixin DivingAbility, FlyingAbility

     assert new JamesBondVehicle().fly() ==
            "I'm the James Bond's vehicle and I fly!"
     assert new JamesBondVehicle().dive() ==
            "I'm the James Bond's vehicle and I dive!"

As another example, consider the following class definitions:

     class Student {
         List schedule = []
         def addLecture(String lecture) { schedule << lecture }
     }

     class Worker {
         List schedule = []
         def addMeeting(String meeting) { schedule << meeting }
     }

We can mimic a form of multiple inheritance as follows:

     class CollegeStudent {
         static { mixin Student, Worker }
     }
     new CollegeStudent().with {
         addMeeting('Performance review with Boss')
         addLecture('Learn about Groovy Mixins')
         println schedule
         println mixedIn[Student].schedule
         println mixedIn[Worker].schedule
     }

Which outputs these lines when run:

     [Performance review with Boss]
     [Learn about Groovy Mixins]
     [Performance review with Boss]

Perhaps some explanation is required here. The methods and properties of Student and Worker are added to CollegeStudent. Worker is added last, so for overlapping methods, its methods will be used, e.g. when calling `schedule`, it will be the schedule property (getSchedule method) from Worker that is used. The schedule property from Student will be shadowed but the `mixedIn` notation allows us to get to that too if we need as the last two lines show.

We can also be a little more dynamic and not require the CollegeStudent class to be defined at all, e.g.:

     def cs = new Object()
     cs.metaClass {
         mixin Student, Worker
         getSchedule {
             mixedIn[Student].schedule + mixedIn[Worker].schedule
         }
     }
     cs.with {
         addMeeting('Performance review with Boss')
         addLecture('Learn about Groovy Mixins')
         println schedule
     }

Which outputs this line when run:

     [Learn about Groovy Mixins, Performance review with Boss]

As another example, we can also define a no dup queue by mixing in some Queue and Set functionality as follows:

     def ndq = new Object()
     ndq.metaClass {
         mixin ArrayDeque
         mixin HashSet
         leftShift = { Object o  ->
             if (!mixedIn[Set].contains(o)) {
                 mixedIn[Queue].push(o)
                 mixedIn[Set].add(o)
             }
         }
     }
     ndq << 1
     ndq << 2
     ndq << 1
     assert ndq.size() == 2

As a final example, we sometimes need to pass such mixed in classes or objects into Java methods which require a given static type but the ExpandoMetaClass mixin approach uses a very dynamic approach based on duck typing rather than static interface definitions, so doesn't by default produce objects matching the required static type. Luckily, there is a mixins capability within ExpandoMetaClass which supports the use of Groovy's common 'as StaticType' notation to produce an object having the correct static type so that it can be passed to the Java method call in question. A slightly contrived example illustrating this feature:

     class CustomComparator implements Comparator {
         int compare(Object a, b) { return a.size() - b.size() }
     }

     class CustomCloseable implements Closeable {
         void close() { println 'Lights out - I am closing' }
     }

     import static mypackage.IOUtils.closeQuietly
     import static java.util.Collections.sort
     def o = new Object()
     o.metaClass.mixin CustomComparator, CustomCloseable
     def items = ['a', 'bbb', 'cc']
     sort(items, o as Comparator)
     println items                // => [a, cc, bbb]
     closeQuietly(o as Closeable) // => Lights out - I am closing

Further details

When using the default implementations of MetaClass, methods are only allowed to be added before initialize() is called. In other words you create a new MetaClass, add some methods and then call initialize(). If you attempt to add new methods after initialize() has been called, an error will be thrown. This is to ensure that the MetaClass can operate appropriately in multithreaded environments as it forces you to do all method additions at the beginning, before using the MetaClass.

ExpandoMetaClass differs here from the default in that it allows you to add methods after initialize has been called. This is done by setting the initialize flag internally to false and then add the methods. Since this is not thread safe it has to be done in a synchronized block. The methods to check for modification and initialization are therefore synchronized as well. Any method call done through this metaclass will first check if the it is synchronized. Should this happen during a modification, then the method cannot be selected or called unless the modification is completed.

Since:
  1.5

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `protected class`
  `ExpandoMetaClass.ExpandoMetaConstructor`
  Handles the ability to use the left shift operator to append new constructors
  `protected class`
  `ExpandoMetaClass.ExpandoMetaProperty`
  Instances of this class are returned when using the `<<` left shift operator.

  ## Nested classes/interfaces inherited from class groovy.lang.MetaClassImpl

  `MetaClassImpl.MetaConstructor`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final String`
  `CONSTRUCTOR`
  Pseudo-property used by the expando DSL to define constructors.
  `boolean`
  `inRegistry`
  Indicates whether this expando meta class is registered in the global registry.
  `static final String`
  `STATIC_QUALIFIER`
  Pseudo-property used by the expando DSL to define static members.

  ### Fields inherited from class groovy.lang.MetaClassImpl

  `EMPTY_ARGUMENTS, getPropertyMethod, INVOKE_METHOD_METHOD, invokeMethodMethod, isGroovyObject, isMap, metaMethodIndex, METHOD_MISSING, PROPERTY_MISSING, registry, setPropertyMethod, STATIC_METHOD_MISSING, STATIC_PROPERTY_MISSING, theCachedClass, theClass`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `ExpandoMetaClass(MetaClassRegistry registry, Class theClass, boolean register, boolean allowChangesAfterInit, MetaMethod[] add)`
  Creates an expando meta class bound to a specific registry.
  `ExpandoMetaClass(Class theClass)`
  Constructs a new ExpandoMetaClass instance for the given class
  `ExpandoMetaClass(Class theClass, boolean register)`
  Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
  `ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit)`
  Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
  `ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit, MetaMethod[] add)`
  Creates an expando meta class with explicit registry behaviour and additional methods.
  `ExpandoMetaClass(Class theClass, boolean register, MetaMethod[] add)`
  Creates an expando meta class with optional global registration and additional initial methods.
  `ExpandoMetaClass(Class theClass, MetaMethod[] add)`
  Creates an unregistered expando meta class with additional initial methods.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `addMixinClass(MixinInMetaClass mixin)`
  `void`
  `addMixinClass$$bridge(MixinInMetaClass mixin)`
  Deprecated.
  use `addMixinClass(MixinInMetaClass)`
  `Object`
  `castToMixedType(Object obj, Class type)`
  Returns the mixed-in view of an object for the requested mixin type.
  `protected void`
  `checkInitalised()`
  checks if the initialisation of the class id complete.
  `ExpandoMetaClass`
  `define(Closure closure)`
  Executes the expando definition DSL against this meta class.
  `static void`
  `disableGlobally()`
  Call to disable the global use of ExpandoMetaClass
  `static void`
  `enableGlobally()`
  Call to enable global use of ExpandoMetaClass within the registry.
  `MetaMethod`
  `findMixinMethod(String methodName, Class[] arguments)`
  Searches for a matching mixin method.
  `List<MetaMethod>`
  `getExpandoMethods()`
  Returns a list of expando MetaMethod instances added to this ExpandoMetaClass
  `Collection<MetaProperty>`
  `getExpandoProperties()`
  Returns a list of MetaBeanProperty instances added to this ExpandoMetaClass
  `Collection`
  `getExpandoSubclassMethods()`
  Returns the subclass-scoped expando methods registered on this meta class.
  `Class`
  `getJavaClass()`
  `MetaClass`
  `getMetaClass()`
  Returns the metaclass for a given class.
  `MetaProperty`
  `getMetaProperty(String name)`
  Looks up an existing MetaProperty by name
  `List<MetaMethod>`
  `getMethods()`
  Overrides the behavior of parent getMethods() method to make MetaClass aware of added Expando methods
  `List<MetaProperty>`
  `getProperties()`
  Returns the available properties for this type.
  `Object`
  `getProperty(Class sender, Object object, String name, boolean useSuper, boolean fromInsideClass)`
  Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
  `Object`
  `getProperty(Object object, String name)`
  Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
  `Object`
  `getProperty(String property)`
  Retrieves a property value.
  `String`
  `getPropertyForSetter(String setterName)`
  Returns a property name equivalent for the given setter name or null if it is not a getter
  `protected Object`
  `getSubclassMetaMethods(String methodName)`
  Returns subclass-scoped meta methods contributed by specialized meta classes.
  `boolean`
  `hasCustomInvokeMethod()`
  Whether this metaclass has a custom `invokeMethod` registration.
  `boolean`
  `hasCustomStaticInvokeMethod()`
  indicates is the metaclass method invocation for static methods is done through a custom invoker object.
  `boolean`
  `hasMetaMethod(String name, Class[] args)`
  Checks whether a MetaMethod for the given name and arguments exists
  `boolean`
  `hasMetaProperty(String name)`
  Returns true if the MetaClass has the given property
  `void`
  `initialize()`
  Complete the initialisation process.
  `Object`
  `invokeConstructor(Object[] arguments)`
  Invokes a constructor for the given arguments.
  `Object`
  `invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass)`
  Overrides default implementation just in case invokeMethod has been overridden by ExpandoMetaClass
  `Object`
  `invokeMethod(String name, Object args)`
  Invokes the given method.
  `Object`
  `invokeStaticMethod(Object object, String methodName, Object[] arguments)`
  Overrides default implementation just in case a static invoke method has been set on ExpandoMetaClass
  `protected boolean`
  `isInitialized()`
  Checks if the metaclass is initialized.
  `boolean`
  `isModified()`
  Returns whether this MetaClassImpl has been modified.
  `boolean`
  `isSetter(String name, CachedClass[] args)`
  Determines whether the supplied method signature represents a Groovy bean setter.
  `static boolean`
  `isValidExpandoProperty(String property)`
  Checks whether a property name is available for the expando DSL.
  `protected void`
  `onGetPropertyFoundInHierarchy(MetaMethod method)`
  Callback invoked when a `getProperty` implementation is discovered.
  `protected void`
  `onInvokeMethodFoundInHierarchy(MetaMethod method)`
  Callback invoked when an `invokeMethod` implementation is discovered.
  `protected void`
  `onSetPropertyFoundInHierarchy(MetaMethod method)`
  Callback invoked when a `setProperty` implementation is discovered.
  `protected void`
  `onSuperMethodFoundInHierarchy(MetaMethod method)`
  Callback invoked when a super-class method is discovered during initialization.
  `protected void`
  `onSuperPropertyFoundInHierarchy(MetaBeanProperty property)`
  Callback invoked when a super-class bean property is discovered during initialization.
  `protected void`
  `performOperationOnMetaClass(Runnable runner)`
  Performs a mutating expando operation while coordinating initialization state and locks.
  `void`
  `refreshInheritedMethods(Set modifiedSuperExpandos)`
  Called from ExpandoMetaClassCreationHandle in the registry if it exists to set up inheritance handling
  `void`
  `registerBeanProperty(String property, Object newValue)`
  Registers a new bean property.
  `void`
  `registerInstanceMethod(MetaMethod metaMethod)`
  Registers a new instance method.
  `void`
  `registerInstanceMethod(String name, Closure closure)`
  Registers a new instance method.
  `protected void`
  `registerStaticMethod(String name, Closure callable)`
  Registers a new static expando method using the closure's declared parameter types.
  `protected void`
  `registerStaticMethod(String name, Closure callable, Class[] paramTypes)`
  Registers a new static method for the given method name and closure on this MetaClass
  `void`
  `registerSubclassInstanceMethod(MetaMethod metaMethod)`
  Registers a subclass-scoped meta method.
  `void`
  `registerSubclassInstanceMethod(String name, Class klazz, Closure closure)`
  Registers an instance method contribution that only applies to the supplied subclass.
  `MetaMethod`
  `retrieveConstructor(Object[] args)`
  This is a helper method which is used only by indy.
  `protected void`
  `setInitialized(boolean b)`
  Updates the initialization flag for this meta class.
  `void`
  `setMetaClass(MetaClass metaClass)`
  Allows the MetaClass to be replaced with a derived implementation.
  `void`
  `setProperty(Class sender, Object object, String name, Object newValue, boolean useSuper, boolean fromInsideClass)`
  Overrides default implementation just in case setProperty method has been overridden by ExpandoMetaClass
  `void`
  `setProperty(String property, Object newValue)`
  Sets the given property to the new value.

  ### Methods inherited from class groovy.lang.MetaClassImpl

  `addMetaBeanProperty, addMetaMethod, addMetaMethodToIndex, addNewInstanceMethod, addNewStaticMethod, applyPropertyDescriptors, checkIfGroovyObjectMethod, chooseConstructor, chooseMethod, chooseNamedArgCompatibleConstructor, clearInvocationCaches, createErrorMessageForAmbiguity, createTransformMetaMethod, doChooseMostSpecificParams, dropMethodCache, dropStaticMethodCache, findMethodInClassHierarchy, findOwnMethod, findPropertyInClassHierarchy, getAdditionalMetaMethods, getAttribute, getAttribute, getAttribute, getClassInfo, getClassNode, getEffectiveGetMetaProperty, getMetaMethod, getMetaMethods, getMethodWithCaching, getMethodWithCaching, getMethodWithoutCaching, getNonClosureOuter, getRegistry, getStaticMetaMethod, getSuperClasses, getTheCachedClass, getTheClass, getVersion, handleMatches, hasProperty, incVersion, invokeMethod, invokeMethod, invokeMissingMethod, invokeMissingProperty, invokeStaticMissingProperty, isGroovyObject, isPermissivePropertyAccess, onMixinMethodFound, pickMethod, reinitialize, respondsTo, respondsTo, retrieveConstructor, retrieveStaticMethod, selectConstructorAndTransformArguments, setAttribute, setAttribute, setPermissivePropertyAccess, setProperties, setProperty, toString`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### CONSTRUCTOR

    public static final String CONSTRUCTOR
    Pseudo-property used by the expando DSL to define constructors.
    See Also:
      - Constant Field Values

  - ### STATIC_QUALIFIER

    public static final String STATIC_QUALIFIER
    Pseudo-property used by the expando DSL to define static members.
    See Also:
      - Constant Field Values

  - ### inRegistry

    public boolean inRegistry
    Indicates whether this expando meta class is registered in the global registry.

- ## Constructor Details

  - ### ExpandoMetaClass

    public ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit, MetaMethod[] add)
    Creates an expando meta class with explicit registry behaviour and additional methods.
    Parameters:
      `theClass` - the enhanced class
      `register` - whether the meta class should be registered globally
      `allowChangesAfterInit` - whether mutation is allowed after initialization
      `add` - additional meta methods to seed the meta class with

  - ### ExpandoMetaClass

    public ExpandoMetaClass(MetaClassRegistry registry, Class theClass, boolean register, boolean allowChangesAfterInit, MetaMethod[] add)
    Creates an expando meta class bound to a specific registry.
    Parameters:
      `registry` - the meta class registry to work with
      `theClass` - the enhanced class
      `register` - whether the meta class should be registered globally
      `allowChangesAfterInit` - whether mutation is allowed after initialization
      `add` - additional meta methods to seed the meta class with

  - ### ExpandoMetaClass

    public ExpandoMetaClass(Class theClass)
    Constructs a new ExpandoMetaClass instance for the given class
    Parameters:
      `theClass` - The class that the MetaClass applies to

  - ### ExpandoMetaClass

    public ExpandoMetaClass(Class theClass, MetaMethod[] add)
    Creates an unregistered expando meta class with additional initial methods.
    Parameters:
      `theClass` - the enhanced class
      `add` - additional meta methods to seed the meta class with

  - ### ExpandoMetaClass

    public ExpandoMetaClass(Class theClass, boolean register)
    Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
    Parameters:
      `theClass` - The class that the MetaClass applies to
      `register` - True if the MetaClass should be registered inside the MetaClassRegistry. This defaults to true and ExpandoMetaClass will affect all instances if changed

  - ### ExpandoMetaClass

    public ExpandoMetaClass(Class theClass, boolean register, MetaMethod[] add)
    Creates an expando meta class with optional global registration and additional initial methods.
    Parameters:
      `theClass` - the enhanced class
      `register` - whether the meta class should be registered globally
      `add` - additional meta methods to seed the meta class with

  - ### ExpandoMetaClass

    public ExpandoMetaClass(Class theClass, boolean register, boolean allowChangesAfterInit)
    Constructs a new ExpandoMetaClass instance for the given class optionally placing the MetaClass in the MetaClassRegistry automatically
    Parameters:
      `theClass` - The class that the MetaClass applies to
      `register` - True if the MetaClass should be registered inside the MetaClassRegistry. This defaults to true and ExpandoMetaClass will affect all instances if changed
      `allowChangesAfterInit` - Should the metaclass be modifiable after initialization. Default is false.

- ## Method Details

  - ### findMixinMethod

    public MetaMethod findMixinMethod(String methodName, Class[] arguments)
    Searches for a matching mixin method.
    Overrides:
      `findMixinMethod` in class `MetaClassImpl`
    Parameters:
      `methodName` - the method name
      `arguments` - the parameter types
    Returns:
      the matching mixin method, or `null` if none is found

  - ### onInvokeMethodFoundInHierarchy

    protected void onInvokeMethodFoundInHierarchy(MetaMethod method)
    Callback invoked when an `invokeMethod` implementation is discovered.
    Overrides:
      `onInvokeMethodFoundInHierarchy` in class `MetaClassImpl`
    Parameters:
      `method` - the discovered handler

  - ### onSuperMethodFoundInHierarchy

    protected void onSuperMethodFoundInHierarchy(MetaMethod method)
    Callback invoked when a super-class method is discovered during initialization.
    Overrides:
      `onSuperMethodFoundInHierarchy` in class `MetaClassImpl`
    Parameters:
      `method` - the inherited method

  - ### onSuperPropertyFoundInHierarchy

    protected void onSuperPropertyFoundInHierarchy(MetaBeanProperty property)
    Callback invoked when a super-class bean property is discovered during initialization.
    Overrides:
      `onSuperPropertyFoundInHierarchy` in class `MetaClassImpl`
    Parameters:
      `property` - the inherited property

  - ### onSetPropertyFoundInHierarchy

    protected void onSetPropertyFoundInHierarchy(MetaMethod method)
    Callback invoked when a `setProperty` implementation is discovered.
    Overrides:
      `onSetPropertyFoundInHierarchy` in class `MetaClassImpl`
    Parameters:
      `method` - the discovered handler

  - ### onGetPropertyFoundInHierarchy

    protected void onGetPropertyFoundInHierarchy(MetaMethod method)
    Callback invoked when a `getProperty` implementation is discovered.
    Overrides:
      `onGetPropertyFoundInHierarchy` in class `MetaClassImpl`
    Parameters:
      `method` - the discovered handler

  - ### isModified

    public boolean isModified()
    Returns whether this MetaClassImpl has been modified. Since MetaClassImpl is not designed for modification this method always returns false
    Specified by:
      `isModified` in interface `MutableMetaClass`
    Overrides:
      `isModified` in class `MetaClassImpl`
    Returns:
      false

  - ### registerSubclassInstanceMethod

    public void registerSubclassInstanceMethod(String name, Class klazz, Closure closure)
    Registers an instance method contribution that only applies to the supplied subclass.
    Parameters:
      `name` - the method name
      `klazz` - the subclass receiving the method
      `closure` - the implementation closure

  - ### registerSubclassInstanceMethod

    public void registerSubclassInstanceMethod(MetaMethod metaMethod)
    Registers a subclass-scoped meta method.
    Parameters:
      `metaMethod` - the method to register

  - ### addMixinClass$$bridge

    @Deprecated public void addMixinClass$$bridge(MixinInMetaClass mixin)
    Deprecated.
    use `addMixinClass(MixinInMetaClass)`
    Legacy bridge retained for binary compatibility with earlier expando mixin APIs.
    Parameters:
      `mixin` - the mixin definition to add

  - ### addMixinClass

    public boolean addMixinClass(MixinInMetaClass mixin)
    Since:
      6.0.0

  - ### castToMixedType

    public Object castToMixedType(Object obj, Class type)
    Returns the mixed-in view of an object for the requested mixin type.
    Parameters:
      `obj` - the receiver object
      `type` - the requested mixin type
    Returns:
      the mixin instance, or `null` if the type is not mixed in

  - ### enableGlobally

    public static void enableGlobally()
    Call to enable global use of ExpandoMetaClass within the registry. This has the advantage that inheritance will function correctly and metaclass modifications will also apply to existing objects, but has a higher memory usage on the JVM than normal Groovy

  - ### disableGlobally

    public static void disableGlobally()
    Call to disable the global use of ExpandoMetaClass

  - ### initialize

    public void initialize()
    Complete the initialisation process. After this method is called no methods should be added to the metaclass. Invocation of methods or access to fields/properties is forbidden unless this method is called. This method should contain any initialisation code, taking a longer time to complete. An example is the creation of the Reflector. It is suggested to synchronize this method.
    Specified by:
      `initialize` in interface `MetaClass`
    Overrides:
      `initialize` in class `MetaClassImpl`

  - ### isInitialized

    protected boolean isInitialized()
    Checks if the metaclass is initialized.
    Overrides:
      `isInitialized` in class `MetaClassImpl`
    Returns:
      `true` once initialization completed
    See Also:
      - `MetaClassImpl.isInitialized()`

  - ### setInitialized

    protected void setInitialized(boolean b)
    Updates the initialization flag for this meta class.
    Overrides:
      `setInitialized` in class `MetaClassImpl`
    Parameters:
      `b` - the new initialization state

  - ### invokeConstructor

    public Object invokeConstructor(Object[] arguments)
    Invokes a constructor for the given arguments. The MetaClass will attempt to pick the best argument which matches the types of the objects passed within the arguments array
    Specified by:
      `invokeConstructor` in interface `MetaObjectProtocol`
    Overrides:
      `invokeConstructor` in class `MetaClassImpl`
    Parameters:
      `arguments` - The arguments to the constructor
    Returns:
      An instance of the java.lang.Class that this MetaObjectProtocol object applies to

  - ### getMetaClass

    public MetaClass getMetaClass()
    Returns the metaclass for a given class.
    Specified by:
      `getMetaClass` in interface `GroovyObject`
    Returns:
      the metaClass of this instance

  - ### getProperty

    public Object getProperty(String property)
    Retrieves a property value.
    Specified by:
      `getProperty` in interface `GroovyObject`
    Parameters:
      `property` - the name of the property of interest
    Returns:
      the given property

  - ### isValidExpandoProperty

    public static boolean isValidExpandoProperty(String property)
    Checks whether a property name is available for the expando DSL.
    Parameters:
      `property` - the property name to test
    Returns:
      `true` if the name can be used by the expando DSL

  - ### invokeMethod

    public Object invokeMethod(String name, Object args)
    Invokes the given method.
    Specified by:
      `invokeMethod` in interface `GroovyObject`
    Parameters:
      `name` - the name of the method to call
      `args` - the arguments to use for the method call
    Returns:
      the result of invoking the method

  - ### setMetaClass

    public void setMetaClass(MetaClass metaClass)
    Allows the MetaClass to be replaced with a derived implementation.
    Specified by:
      `setMetaClass` in interface `GroovyObject`
    Parameters:
      `metaClass` - the new metaclass

  - ### setProperty

    public void setProperty(String property, Object newValue)
    Sets the given property to the new value.
    Specified by:
      `setProperty` in interface `GroovyObject`
    Parameters:
      `property` - the name of the property of interest
      `newValue` - the new value for the property

  - ### define

    public ExpandoMetaClass define(@ClosureParams(value=SimpleType.class,options="java.lang.Object") @DelegatesTo(value=groovy.lang.ExpandoMetaClass.DefiningClosure.class,strategy=3) Closure closure)
    Executes the expando definition DSL against this meta class.
    Parameters:
      `closure` - the definition closure
    Returns:
      this meta class

  - ### performOperationOnMetaClass

    protected void performOperationOnMetaClass(Runnable runner)
    Performs a mutating expando operation while coordinating initialization state and locks.
    Parameters:
      `runner` - the operation to execute

  - ### checkInitalised

    protected void checkInitalised()
    checks if the initialisation of the class id complete. This method should be called as a form of assert, it is no way to test if there is still initialisation work to be done. Such logic must be implemented in a different way.
    Overrides:
      `checkInitalised` in class `MetaClassImpl`

  - ### registerBeanProperty

    public void registerBeanProperty(String property, Object newValue)
    Registers a new bean property.
    Parameters:
      `property` - the property name
      `newValue` - the properties initial value

  - ### registerInstanceMethod

    public void registerInstanceMethod(String name, Closure closure)
    Registers a new instance method.
    Parameters:
      `name` - the method name or `"constructor"` for a constructor
      `closure` - the implementation

  - ### registerInstanceMethod

    public void registerInstanceMethod(MetaMethod metaMethod)
    Registers a new instance method.

  - ### getMethods

    public List<MetaMethod> getMethods()
    Overrides the behavior of parent getMethods() method to make MetaClass aware of added Expando methods
    Specified by:
      `getMethods` in interface `MetaClass`
    Specified by:
      `getMethods` in interface `MetaObjectProtocol`
    Overrides:
      `getMethods` in class `MetaClassImpl`
    Returns:
      A list of MetaMethods
    See Also:
      - `MetaObjectProtocol.getMethods()`

  - ### getProperties

    public List<MetaProperty> getProperties()
    Returns the available properties for this type.
    Specified by:
      `getProperties` in interface `MetaClass`
    Specified by:
      `getProperties` in interface `MetaObjectProtocol`
    Overrides:
      `getProperties` in class `MetaClassImpl`
    Returns:
      a list of `MetaProperty` objects
    See Also:
      - `MetaProperty`

  - ### registerStaticMethod

    protected void registerStaticMethod(String name, Closure callable)
    Registers a new static expando method using the closure's declared parameter types.
    Parameters:
      `name` - the method name
      `callable` - the implementation closure

  - ### registerStaticMethod

    protected void registerStaticMethod(String name, Closure callable, Class[] paramTypes)
    Registers a new static method for the given method name and closure on this MetaClass
    Parameters:
      `name` - The method name
      `callable` - The callable Closure

  - ### getSubclassMetaMethods

    protected Object getSubclassMetaMethods(String methodName)
    Returns subclass-scoped meta methods contributed by specialized meta classes.
    Overrides:
      `getSubclassMetaMethods` in class `MetaClassImpl`
    Parameters:
      `methodName` - the method name
    Returns:
      subclass methods for the name, or `null` if none are registered

  - ### getJavaClass

    public Class getJavaClass()
    Returns:
      The Java class enhanced by this MetaClass

  - ### refreshInheritedMethods

    public void refreshInheritedMethods(Set modifiedSuperExpandos)
    Called from ExpandoMetaClassCreationHandle in the registry if it exists to set up inheritance handling
    Parameters:
      `modifiedSuperExpandos` - A list of modified super ExpandoMetaClass

  - ### getExpandoMethods

    public List<MetaMethod> getExpandoMethods()
    Returns a list of expando MetaMethod instances added to this ExpandoMetaClass
    Returns:
      the expandoMethods

  - ### getExpandoSubclassMethods

    public Collection getExpandoSubclassMethods()
    Returns the subclass-scoped expando methods registered on this meta class.
    Returns:
      an unmodifiable view of the registered subclass method entries

  - ### getExpandoProperties

    public Collection<MetaProperty> getExpandoProperties()
    Returns a list of MetaBeanProperty instances added to this ExpandoMetaClass
    Returns:
      the expandoProperties

  - ### invokeMethod

    public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass)
    Overrides default implementation just in case invokeMethod has been overridden by ExpandoMetaClass
    Specified by:
      `invokeMethod` in interface `MetaClass`
    Overrides:
      `invokeMethod` in class `MetaClassImpl`
    Parameters:
      `sender` - The java.lang.Class instance that invoked the method
      `object` - The object which the method was invoked on
      `methodName` - The name of the method
      `originalArguments` - The arguments to the method
      `isCallToSuper` - Whether the method is a call to a super class method
      `fromInsideClass` - Whether the call was invoked from the inside or the outside of the class
    Returns:
      The return value of the method.
    See Also:
      - `MetaClassImpl.invokeMethod(Class, Object, String, Object[], boolean, boolean)`

  - ### invokeStaticMethod

    public Object invokeStaticMethod(Object object, String methodName, Object[] arguments)
    Overrides default implementation just in case a static invoke method has been set on ExpandoMetaClass
    Specified by:
      `invokeStaticMethod` in interface `MetaObjectProtocol`
    Overrides:
      `invokeStaticMethod` in class `MetaClassImpl`
    Parameters:
      `object` - An instance of the class returned by the getTheClass() method or the class itself
      `methodName` - The name of the method
      `arguments` - The arguments to the method
    Returns:
      The return value of the method which is null if the return type is void
    See Also:
      - `MetaClassImpl.invokeStaticMethod(Object, String, Object[])`

  - ### getProperty

    public Object getProperty(Class sender, Object object, String name, boolean useSuper, boolean fromInsideClass)
    Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
    Specified by:
      `getProperty` in interface `MetaClass`
    Overrides:
      `getProperty` in class `MetaClassImpl`
    Parameters:
      `sender` - The java.lang.Class instance that requested the property
      `object` - The Object which the property is being retrieved from
      `name` - The name of the property
      `useSuper` - Whether the call is to a super class property
      `fromInsideClass` - ??
    Returns:
      The property's value.
    See Also:
      - `MetaClassImpl.getProperty(Class, Object, String, boolean, boolean)`

  - ### getProperty

    public Object getProperty(Object object, String name)
    Overrides default implementation just in case getProperty method has been overridden by ExpandoMetaClass
    Specified by:
      `getProperty` in interface `MetaObjectProtocol`
    Overrides:
      `getProperty` in class `MetaClassImpl`
    Parameters:
      `object` - The Object which the property is being retrieved from
      `name` - The name of the property
    Returns:
      The properties value
    See Also:
      - `MetaClassImpl.getProperty(Object, String)`

  - ### setProperty

    public void setProperty(Class sender, Object object, String name, Object newValue, boolean useSuper, boolean fromInsideClass)
    Overrides default implementation just in case setProperty method has been overridden by ExpandoMetaClass
    Specified by:
      `setProperty` in interface `MetaClass`
    Overrides:
      `setProperty` in class `MetaClassImpl`
    Parameters:
      `sender` - The java.lang.Class instance that is mutating the property
      `object` - The Object which the property is being set on
      `name` - The name of the property
      `newValue` - The new value of the property to set
      `useSuper` - Whether the call is to a super class property
      `fromInsideClass` - Whether the call was invoked from the inside or the outside of the class.
    See Also:
      - `MetaClassImpl.setProperty(Class, Object, String, Object, boolean, boolean)`

  - ### getMetaProperty

    public MetaProperty getMetaProperty(String name)
    Looks up an existing MetaProperty by name
    Specified by:
      `getMetaProperty` in interface `MetaObjectProtocol`
    Overrides:
      `getMetaProperty` in class `MetaClassImpl`
    Parameters:
      `name` - The name of the MetaProperty
    Returns:
      The MetaProperty or null if it doesn't exist
    See Also:
      - `MetaObjectProtocol.getMetaProperty(String)`

  - ### hasMetaProperty

    public boolean hasMetaProperty(String name)
    Returns true if the MetaClass has the given property
    Parameters:
      `name` - The name of the MetaProperty
    Returns:
      True it exists as a MetaProperty

  - ### hasMetaMethod

    public boolean hasMetaMethod(String name, Class[] args)
    Checks whether a MetaMethod for the given name and arguments exists
    Parameters:
      `name` - The name of the MetaMethod
      `args` - The arguments to the meta method
    Returns:
      True if the method exists otherwise null

  - ### getPropertyForSetter

    public String getPropertyForSetter(String setterName)
    Returns a property name equivalent for the given setter name or null if it is not a getter
    Parameters:
      `setterName` - The setter name
    Returns:
      The property name equivalent

  - ### isSetter

    public boolean isSetter(String name, CachedClass[] args)
    Determines whether the supplied method signature represents a Groovy bean setter.
    Parameters:
      `name` - the candidate method name
      `args` - the candidate parameter types
    Returns:
      `true` if the signature represents a setter

  - ### hasCustomStaticInvokeMethod

    public boolean hasCustomStaticInvokeMethod()
    indicates is the metaclass method invocation for static methods is done through a custom invoker object.
    Overrides:
      `hasCustomStaticInvokeMethod` in class `MetaClassImpl`
    Returns:
      true - if the method invocation is not done by the metaclass itself

  - ### hasCustomInvokeMethod

    public boolean hasCustomInvokeMethod()
    Whether this metaclass has a custom `invokeMethod` registration.
    Overrides:
      `hasCustomInvokeMethod` in class `MetaClassImpl`
    Returns:
      `true` if a custom invokeMethod is registered
    Since:
      6.0.0

  - ### retrieveConstructor

    public MetaMethod retrieveConstructor(Object[] args)
    This is a helper method which is used only by indy. It is for internal use.
    Overrides:
      `retrieveConstructor` in class `MetaClassImpl`