Package org.codehaus.groovy.reflection

# Class ClassInfo

java.lang.Object
org.codehaus.groovy.reflection.ClassInfo

All Implemented Interfaces:
  `Finalizable`

public class ClassInfo extends Object implements Finalizable
Handle for all information we want to keep about the class

This class handles caching internally and it's advisable to not store references directly to objects of this class. The static factory method `getClassInfo(Class)` should be used to retrieve an instance from the cache. Internally the `Class` associated with a `ClassInfo` instance is kept as `WeakReference`, so it not safe to reference and instance without the Class being either strongly or softly reachable.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static interface`
  `ClassInfo.ClassInfoAction`
  Functional interface for performing actions on `ClassInfo` instances.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `final int`
  `hash`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static void`
  `clearModifiedExpandos()`
  Clears all modified `ExpandoMetaClass` instances for all classes.
  `void`
  `collectLiveIndySwitchPoints(List<SwitchPoint> out)`
  Detaches live SwitchPoint(s) for this class into `out`: the installed MetaClass domain (if any) and the pending domain (if live).
  `SwitchPoint`
  `detachLiveIndySwitchPoint()`
  Detaches live SwitchPoint(s) for this class.
  `void`
  `finalizeReference()`
  Performs any cleanup required after the associated reference has been cleared.
  `static int`
  `fullSize()`
  Returns the total size including soft-referenced (potentially garbage-collectable) entries.
  `static Collection<ClassInfo>`
  `getAllClassInfo()`
  Returns all cached class information across the runtime.
  `ClassLoaderForClassArtifacts`
  `getArtifactClassLoader()`
  Returns the class loader for loading class artifacts (e.g., compiled bytecode).
  `CachedClass`
  `getCachedClass()`
  Returns the cached class representation for this class.
  `static ClassInfo`
  `getClassInfo(Class cls)`
  Retrieves the `ClassInfo` for the given class.
  `SwitchPoint`
  `getIndySwitchPoint()`
  Returns the SwitchPoint for monomorphic indy MOP guards on this class (GROOVY-12191).
  `final MetaClass`
  `getMetaClass()`
  Returns the `MetaClass` for the `Class` associated with this `ClassInfo`.
  `MetaClass`
  `getMetaClass(Object obj)`
  Returns the metaclass for an object.
  `MetaClass`
  `getMetaClassForClass()`
  Returns the most appropriate metaclass for this class.
  `ExpandoMetaClass`
  `getModifiedExpando()`
  Returns the modified `ExpandoMetaClass` for this class, if one exists.
  `SwitchPoint`
  `getPendingIndySwitchPoint()`
  Pending domain for pre-MetaClass link.
  `MetaClass`
  `getPerInstanceMetaClass(Object obj)`
  Returns the per-instance metaclass for the given object, if one has been set.
  `MetaClass`
  `getStrongMetaClass()`
  Returns the strong (immutable) metaclass for this class, if one has been set.
  `final Class<?>`
  `getTheClass()`
  Returns the `Class` associated with this `ClassInfo`.
  `int`
  `getVersion()`
  Returns the version number of this class information.
  `MetaClass`
  `getWeakMetaClass()`
  Returns the weak (mutable) metaclass for this class, if one has been set.
  `boolean`
  `hasPerInstanceMetaClasses()`
  Returns whether this class has any per-instance metaclasses associated with its objects.
  `void`
  `incVersion()`
  Increments the version number and invalidates this class's MetaClass SwitchPoint domain (exact class only).
  `void`
  `invalidateIndySwitchPoint()`
  Invalidates this class's class-level MetaClass domain and pending domain without bumping `getVersion()`.
  `void`
  `lock()`
  Acquires a lock for this class information.
  `static void`
  `onAllClassInfo(ClassInfo.ClassInfoAction action)`
  Executes the given action on all cached class information.
  `static void`
  `remove(Class<?> cls)`
  Removes a `ClassInfo` from the cache.
  `void`
  `setPerInstanceMetaClass(Object obj, MetaClass metaClass)`
  Sets the per-instance metaclass for the given object.
  `void`
  `setStrongMetaClass(MetaClass answer)`
  Sets the strong (immutable) metaclass for this class.
  `void`
  `setWeakMetaClass(MetaClass answer)`
  Sets the weak (mutable) metaclass for this class.
  `static int`
  `size()`
  Returns the number of cached class information entries.
  `void`
  `unlock()`
  Releases the lock for this class information.

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

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

- ## Field Details

  - ### hash

    public final int hash
    See Also:
      - Constant Field Values

- ## Method Details

  - ### getVersion

    public int getVersion()
    Returns the version number of this class information. The version increments when the metaclass is modified (e.g., methods/properties added).
    Returns:
      the current version

  - ### incVersion

    public void incVersion()
    Increments the version number and invalidates this class's MetaClass SwitchPoint domain (exact class only). Called when metaclass modifications occur (e.g., adding methods to an `ExpandoMetaClass`).

    Behavioral change in 6.0 (GROOVY-12191): this method no longer triggers a process-wide call-site flush. It scopes invalidation to this class only. Subtype sites are not retired: stock missing-method / missing-property hierarchy walks re-resolve live on the dynamic route (see `IndyInvalidation`). Callers that previously relied on `incVersion()` as a global “flush everything” hammer should invoke `VMPlugin.invalidateCallSites()` (or `IndyInvalidation.invalidateCategory()`) explicitly when a bulk flush is required. Unrelated classes keep their optimized targets.

    Category enter/leave still bulk-invalidates MetaClass SwitchPoints via `VMPlugin.invalidateCallSites()`. SwitchPoint policy is owned by `IndyInvalidation`; this method only bumps generation then delegates exact-class invalidation.

  - ### getIndySwitchPoint

    public SwitchPoint getIndySwitchPoint()
    Returns the SwitchPoint for monomorphic indy MOP guards on this class (GROOVY-12191). Delegates to `IndyInvalidation.classSwitchPointFor(java.lang.Object)`.
    Returns:
      MetaClass domain if installed, otherwise pending domain
    Since:
      6.0.0

  - ### getPendingIndySwitchPoint

    public SwitchPoint getPendingIndySwitchPoint()
    Pending domain for pre-MetaClass link. Live SwitchPoint allocated lazily.
    Returns:
      pending SwitchPoint
    Since:
      6.0.0

  - ### invalidateIndySwitchPoint

    public void invalidateIndySwitchPoint()
    Invalidates this class's class-level MetaClass domain and pending domain without bumping `getVersion()`. Prefer `incVersion()` when the MetaClass actually changed.
    Since:
      6.0.0

  - ### collectLiveIndySwitchPoints

    public void collectLiveIndySwitchPoints(List<SwitchPoint> out)
    Detaches live SwitchPoint(s) for this class into `out`: the installed MetaClass domain (if any) and the pending domain (if live). Does not create a MetaClass.
    Parameters:
      `out` - destination list (must not be `null`)
    Since:
      6.0.0

  - ### detachLiveIndySwitchPoint

    public SwitchPoint detachLiveIndySwitchPoint()
    Detaches live SwitchPoint(s) for this class. Prefer `collectLiveIndySwitchPoints(java.util.List<java.lang.invoke.SwitchPoint>)` for bulk paths.
    Returns:
      one detached SwitchPoint, or `null`; additional live domains are invalidated immediately so they are not orphaned
    Since:
      6.0.0

  - ### getModifiedExpando

    public ExpandoMetaClass getModifiedExpando()
    Returns the modified `ExpandoMetaClass` for this class, if one exists.
    Returns:
      the modified expando metaclass, or `null` if not modified or not an ExpandoMetaClass

  - ### clearModifiedExpandos

    public static void clearModifiedExpandos()
    Clears all modified `ExpandoMetaClass` instances for all classes. Removes strong references to metaclasses and disassociates them from their class information.

  - ### getTheClass

    public final Class<?> getTheClass()
    Returns the `Class` associated with this `ClassInfo`.

    This method can return `null` if the `Class` is no longer reachable through any strong or soft references. A non-null return value indicates that this `ClassInfo` is valid.

    Returns:
      the `Class` associated with this `ClassInfo`, else `null`

  - ### getCachedClass

    public CachedClass getCachedClass()
    Returns the cached class representation for this class. Lazily initializes on first access.
    Returns:
      the cached class

  - ### getArtifactClassLoader

    public ClassLoaderForClassArtifacts getArtifactClassLoader()
    Returns the class loader for loading class artifacts (e.g., compiled bytecode). Lazily initializes on first access.
    Returns:
      the artifact class loader

  - ### getClassInfo

    public static ClassInfo getClassInfo(Class cls)
    Retrieves the `ClassInfo` for the given class. Lazily creates one if not already cached.
    Parameters:
      `cls` - the class to get information for
    Returns:
      the class information, or `null` if `cls` is `null`

  - ### remove

    public static void remove(Class<?> cls)
    Removes a `ClassInfo` from the cache. This is useful in cases where the Class is parsed from a script, such as when using GroovyClassLoader#parseClass, and is executed for its result but the Class is not retained or cached. Removing the `ClassInfo` associated with the Class will make the Class and its ClassLoader eligible for garbage collection sooner that it would otherwise.
    Parameters:
      `cls` - the Class associated with the ClassInfo to remove from cache

  - ### getAllClassInfo

    public static Collection<ClassInfo> getAllClassInfo()
    Returns all cached class information across the runtime.
    Returns:
      a collection of all cached class info objects

  - ### onAllClassInfo

    public static void onAllClassInfo(ClassInfo.ClassInfoAction action)
    Executes the given action on all cached class information. Allows processing of all classes currently tracked by the runtime.
    Parameters:
      `action` - the action to execute on each ClassInfo

  - ### getStrongMetaClass

    public MetaClass getStrongMetaClass()
    Returns the strong (immutable) metaclass for this class, if one has been set. A strong reference keeps the metaclass in memory regardless of garbage collection.
    Returns:
      the strong metaclass, or `null` if not set

  - ### setStrongMetaClass

    public void setStrongMetaClass(MetaClass answer)
    Sets the strong (immutable) metaclass for this class. Increments the version number and manages ExpandoMetaClass registry.

    On replacement or clear, also invalidates this class's indy SwitchPoint (GROOVY-12191). First install (`null →` MC) only bumps version; exact-class invalidation for the registry event is applied by MetaClass registry listeners or `incVersion()`.

    Parameters:
      `answer` - the metaclass to set, or `null` to clear

  - ### getWeakMetaClass

    public MetaClass getWeakMetaClass()
    Returns the weak (mutable) metaclass for this class, if one has been set. A weak reference allows garbage collection of the metaclass when no longer needed.
    Returns:
      the weak metaclass, or `null` if not set or if it has been garbage collected

  - ### setWeakMetaClass

    public void setWeakMetaClass(MetaClass answer)
    Sets the weak (mutable) metaclass for this class. Clears the strong metaclass and increments the version number.

    On replacement or clear, also invalidates this class's indy SwitchPoint (GROOVY-12191). First install only bumps version.

    Parameters:
      `answer` - the metaclass to set, or `null` to clear

  - ### getMetaClassForClass

    public MetaClass getMetaClassForClass()
    Returns the most appropriate metaclass for this class. Prefers strong metaclass if available, then weak metaclass if valid, otherwise the default.
    Returns:
      the metaclass for this class

  - ### getMetaClass

    public final MetaClass getMetaClass()
    Returns the `MetaClass` for the `Class` associated with this `ClassInfo`. If no `MetaClass` exists one will be created.

    It is not safe to call this method without a `Class` associated with this `ClassInfo`. It is advisable to always retrieve a ClassInfo instance from the cache by using the static factory method `getClassInfo(Class)` to ensure the referenced Class is strongly reachable.

    Returns:
      a `MetaClass` instance

  - ### getMetaClass

    public MetaClass getMetaClass(Object obj)
    Returns the metaclass for an object. If the object has a per-instance metaclass, returns that; otherwise returns this class's metaclass.
    Parameters:
      `obj` - the object to get the metaclass for
    Returns:
      the metaclass for the object

  - ### size

    public static int size()
    Returns the number of cached class information entries.
    Returns:
      the count of cached ClassInfo instances

  - ### fullSize

    public static int fullSize()
    Returns the total size including soft-referenced (potentially garbage-collectable) entries.
    Returns:
      the full count of class information entries

  - ### lock

    public void lock()
    Acquires a lock for this class information. Used to synchronize modifications to metaclass and per-instance metaclass maps.

  - ### unlock

    public void unlock()
    Releases the lock for this class information.

  - ### getPerInstanceMetaClass

    public MetaClass getPerInstanceMetaClass(Object obj)
    Returns the per-instance metaclass for the given object, if one has been set.
    Parameters:
      `obj` - the object to get the per-instance metaclass for
    Returns:
      the per-instance metaclass, or `null` if not set

  - ### setPerInstanceMetaClass

    public void setPerInstanceMetaClass(Object obj, MetaClass metaClass)
    Sets the per-instance metaclass for the given object. Per-instance metaclasses override the class-level metaclass for that specific object.
    Parameters:
      `obj` - the object to associate with a metaclass
      `metaClass` - the metaclass to set, or `null` to remove the association

  - ### hasPerInstanceMetaClasses

    public boolean hasPerInstanceMetaClasses()
    Returns whether this class has any per-instance metaclasses associated with its objects.
    Returns:
      `true` if one or more per-instance metaclasses have been set; `false` otherwise

  - ### finalizeReference

    public void finalizeReference()
    Description copied from interface: `Finalizable`
    Performs any cleanup required after the associated reference has been cleared.
    Specified by:
      `finalizeReference` in interface `Finalizable`