Skip to content
Luke Hutchison edited this page Aug 11, 2026 · 8 revisions

See also the ClassGraph API overview.

Contents

FieldInfo

Holds information about one field of a class. Obtained by calling ClassInfo#getFieldInfo() and similar methods.

  • Properties: (N.B. call .enableFieldInfo() before .scan() to enable field scanning, and call .ignoreFieldVisibility() before .scan() if you want to scan non-public fields.)
    • .getName() returns the name of the field as a String.
    • .getClassName() returns the name of the declaring class (i.e. the class that declares the field).
    • .getClassInfo() returns the ClassInfo object for the declaring class (i.e. the class that declares the field).
    • .getModifiers() returns the field modifier bits as an int.
    • .getModifiersString() returns the field modifiers as a String (e.g. "public static").
    • .isPublic() returns true if the field is public.
    • .isProtected() returns true if the field is protected.
    • .isPrivate() returns true if the field is private.
    • .isStatic() returns true if the field is static.
    • .isFinal() returns true if the field is final.
    • .isTransient() returns true if the field is transient.
    • .isSynthetic() returns true if the field is synthetic.
    • .isEnum() returns true if the field is an enum constant.
    • .toStringWithSimpleNames() returns a simpler rendering of the field than FieldInfo#toString(), by using only the simple name of any classes or annotations in the field's type.
  • Type:
    • .getTypeSignature() returns the type signature of the field (including any generic type parameters) as a TypeSignature, if available, otherwise returns null.

      🛑 ClassGraph makes no attempt to resolve type variables in the types of fields. If you need concrete types for a specific type context, you will need to do the type substitution yourself.

    • .getTypeSignatureString() returns the type signature of the field (including any generic type parameters) as a raw internal Java type signature string, or null if there is no generic type signature.
    • .getTypeDescriptor() returns the type descriptor of the field (without generic type parameters) as a TypeSignature.
    • .getTypeDescriptorString() returns the type descriptor of the field (without any generic type parameters) as a raw internal Java type descriptor string.
    • .getTypeSignatureOrTypeDescriptor() returns the type signature of the field, if available, otherwise returns the type descriptor. This is usually the method you want.
    • .getTypeSignatureOrTypeDescriptorString() returns the raw internal type signature string of the field, if available, otherwise returns the raw internal type descriptor string of the field.
  • Constant initializer value:
    • .getConstantInitializerValue() returns the constant initializer value of the field, or null if it has none. Requires ClassGraph#enableStaticFinalFieldConstantInitializerValues(), and throws IllegalStateException if that was not called before scanning.

      💡 Only fields with constant initializers have a value here -- in practice, fields of primitive type and String constants. The value may be the result of basic math or string concatenation that the compiler could evaluate, but never the result of object construction, other than for String.

      💡 It is up to the compiler whether a constant-valued field is assigned as a constant in the field definition itself, or assigned in a static or instance initializer block or in the constructor, so not every field that looks constant in the source has a constant initializer value in the classfile.

      💡 A field initialized to a constant primitive value returns the constant wrapped in a boxed type (e.g. Integer for a primitive int-typed constant value).

  • Annotations:

    💡 Every annotation getter comes in an All form and a Direct form. The All form also includes meta-annotations -- the annotations on the field's own annotations, transitively. The Direct form includes only the annotations written on the field itself.

    • .getAllAnnotationInfo() / .getDirectAnnotationInfo() returns the annotations on this field as an AnnotationInfoList.
    • .hasAnnotation(String annotationName | Class<? extends Annotation> annotationClass) returns true if the field has the given annotation.
    • .getAllAnnotationInfo(String annotationName | Class<? extends Annotation> annotationClass) / .getDirectAnnotationInfo(...) returns the AnnotationInfo object for the given non-@Repeatable field annotation, or null if none.
    • .getAllAnnotationInfoRepeatable(String annotationName | Class<? extends Annotation> annotationClass) / .getDirectAnnotationInfoRepeatable(...) returns the AnnotationInfo objects for the given @Repeatable field annotation, as an AnnotationInfoList, or the empty list if none.
  • Dependencies:
    • .getClassDependencies() returns a ClassInfoList of the classes referenced by this field: the classes named in its type descriptor and type signature, and the classes of the annotations on it. Unlike ClassInfo#getClassDependencies(), this does not require .enableInterClassDependencies(), since the information comes from the field's own signature and annotations. Only classes that were themselves encountered during the scan are returned -- call .enableExternalClasses() before scanning to also get classes outside the accepted packages.

The effect of .ignoreFieldVisibility()

If you call ClassGraph#ignoreFieldVisibility() before calling scan(), then non-public fields will be scanned, and FieldInfo objects will be added to the ScanResult for any non-public fields encountered while scanning classes.

Note that ClassGraph differs in its behavior from the Java reflection API. You will notice the following differences in behavior:

  • Java reflection:

    • Class#getFields() returns public fields but not non-public fields, for a class and all its superclasses.
    • Class#getDeclaredFields() returns public and non-public fields for a class, but not its superclasses.
  • ClassGraph:

    • ClassInfo#getFieldInfo() returns fields for a class and all its superclasses. Only public fields are returned unless ClassGraph#ignoreFieldVisibility() was called, then both public and non-public fields are returned.
    • ClassInfo#getDeclaredFieldInfo() returns fields for a class but not its superclasses. Only public fields are returned unless ClassGraph#ignoreFieldVisibility() was called, then both public and non-public fields are returned.

This difference in behavior is intended to separate the concerns of whether or not to obtain field info from superclasses from whether or not to return non-public fields, making it simpler with the ClassGraph API to find non-public fields in superclasses, and/or to filter out non-public fields from a given base class, if they are not needed. With the Java reflection API, you cannot get non-public fields from superclasses using Sub.class.getFields() -- if you do want the non-public fields, you have to iterate up through the superclass hierarchy and call .getDeclaredFields() on each superclass. Conversely, with the Java reflection API you cannot request only public fields that are declared in a base class but not its superclasses (when calling .getDeclaredFields()).

With ClassGraph, you can separately decide (1) whether or not to include fields from superclasses (by calling .getDeclaredFieldInfo() if you want only the fields of a class but not its superclasses, or .getFieldInfo() if you want the fields of a class and all of its superclasses), and (2) whether or not to include non-public fields in results (by calling .ignoreFieldVisibility() to enable non-public fields).

To illustrate, given the following classes:

public class Super {
    public int publicSuper;
    private int privateSuper;
}

public class Sub extends Super {
    public int publicSub;
    private int privateSub;
}

The following results are obtained:

Non-declared fields of Super:

Mechanism Method call Result
Java reflection Super.class.getFields() publicSuper
ClassGraph superClassInfo.getFieldInfo() publicSuper
ClassGraph after .ignoreFieldVisibility() superClassInfo.getFieldInfo() publicSuper, privateSuper

Non-declared fields of Sub:

Mechanism Method call Result
Java reflection Sub.class.getFields() publicSuper, publicSub
ClassGraph subClassInfo.getFieldInfo() publicSuper, publicSub
ClassGraph after .ignoreFieldVisibility() subClassInfo.getFieldInfo() publicSuper, publicSub, privateSuper, privateSub

Declared fields of Super:

Mechanism Method call Result
Java reflection Super.class.getDeclaredFields() publicSuper, privateSuper
ClassGraph superClassInfo.getDeclaredFieldInfo() publicSuper
ClassGraph after .ignoreFieldVisibility() superClassInfo.getDeclaredFieldInfo() publicSuper, privateSuper

Declared fields of Sub:

Mechanism Method call Result
Java reflection Sub.class.getDeclaredFields() publicSub, privateSub
ClassGraph subClassInfo.getDeclaredFieldInfo() publicSub
ClassGraph after .ignoreFieldVisibility() subClassInfo.getDeclaredFieldInfo() publicSub, privateSub

FieldInfoList

Extends ArrayList<FieldInfo> with the following convenience methods:

  • .asMap() returns the FieldInfoList as a Map<String, FieldInfo> mapping the field name to the corresponding FieldInfo object.
  • .getNames() returns a list of the names of the fields in this list as a List<String>.
  • .getAsStrings() returns a list of the result of calling .toString() on each FieldInfo object in this list, producing a List<String> of String representations of each field, including annotations, modifiers, generic type params, and field name.
    • .getAsStringsWithSimpleNames() works like .getAsStrings(), but uses only the simple name of any referenced classes, by calling .toStringWithSimpleNames() on each list element rather than .toString().
  • .containsName(String fieldName) returns true if a field of the given name is contained in this list.
  • .get(String fieldName) returns the FieldInfo object in this list with the requested name, if present, otherwise returns null.
  • .filter(Predicate<FieldInfo> filter) returns a FieldInfoList that is a subset of the original list, obtained by applying the given predicate to each FieldInfo object in the list, e.g. .filter(FieldInfo::isStatic).

Clone this wiki locally