Java : AccessibleObject with Examples

AccessibleObject (Java SE 18 & JDK 18) API Examples.
You will find code examples on most AccessibleObject methods.


Summary

The AccessibleObject class is the base class for Field, Method, and Constructor objects (known as reflected objects). It provides the ability to flag a reflected object as suppressing checks for Java language access control when it is used.

Class diagram

public class AccessTest {
    private int num = 100;
}
final var field = AccessTest.class.getDeclaredField("num");
final var obj = new AccessTest();

System.out.println(field.canAccess(obj)); // false
//field.getInt(obj); // IllegalAccessException

System.out.println(field.trySetAccessible()); // true
System.out.println(field.canAccess(obj)); // true

System.out.println(field.getInt(obj)); // 100

Constructors

AccessibleObject ()

Deprecated.

Deprecated.

Methods

final boolean canAccess (Object obj)

Test if the caller can access this reflected object.

public class AccessTest {
    private int num = 100;
}
final AccessibleObject accessibleObject = AccessTest.class.getDeclaredField("num");
final var obj = new AccessTest();

System.out.println(accessibleObject.canAccess(obj)); // false
System.out.println(accessibleObject.trySetAccessible()); // true
System.out.println(accessibleObject.canAccess(obj)); // true

<T extends Annotation> T getAnnotation (Class<T> annotationClass)

Returns this element's annotation for the specified type if such an annotation is present, else null.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Foo {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Bar {
}

public class A {
    @Foo
    public int num;

    @Bar
    public void aaa() {
    }
}
final AccessibleObject field = A.class.getDeclaredField("num");
System.out.println(field); // public int A.num

System.out.println(field.isAnnotationPresent(Foo.class)); // true

final var ret1 = field.getAnnotation(Foo.class);
System.out.println(ret1.annotationType().getSimpleName()); // Foo

System.out.println(field.isAnnotationPresent(Bar.class)); // false

final var ret2 = field.getAnnotation(Bar.class);
System.out.println(ret2); // null
final AccessibleObject method = A.class.getDeclaredMethod("aaa");
System.out.println(method); // public void A.aaa()

System.out.println(method.isAnnotationPresent(Foo.class)); // false

final var ret1 = method.getAnnotation(Foo.class);
System.out.println(ret1); // null

System.out.println(method.isAnnotationPresent(Bar.class)); // true

final var ret2 = method.getAnnotation(Bar.class);
System.out.println(ret2.annotationType().getSimpleName()); // Bar

Annotation[] getAnnotations ()

Returns annotations that are present on this element.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Foo {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Bar {
}

public class A {
    @Foo
    @Bar
    public int num;
}
final var accessibleObject = A.class.getDeclaredField("num");
System.out.println(accessibleObject);

System.out.println("-- annotations --");
for (final var a : accessibleObject.getAnnotations()) {
    System.out.println(a.annotationType().getSimpleName());
}

// Result
// ↓
//public int A.num
//-- annotations --
//Foo
//Bar

<T extends Annotation> T[] getAnnotationsByType (Class<T> annotationClass)

Returns annotations that are associated with this element.

@Repeatable(FooArray.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Foo {
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FooArray {
    Foo[] value();
}

public class A {
    @Foo("a1")
    @Foo("a2")
    public int num;
}
final AccessibleObject accessibleObject = A.class.getDeclaredField("num");
System.out.println(accessibleObject);

System.out.println("-- annotations --");
for (final var a : accessibleObject.getAnnotationsByType(Foo.class)) {
    System.out.println(a.annotationType().getSimpleName() + " : " + a.value());
}

// Result
// ↓
//public int A.num
//-- annotations --
//Foo : a1
//Foo : a2

<T extends Annotation> T getDeclaredAnnotation (Class<T> annotationClass)

Returns this element's annotation for the specified type if such an annotation is directly present, else null.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Foo {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Bar {
}

public class A {
    @Foo
    public int num;

    @Bar
    public void aaa() {
    }
}
final AccessibleObject field = A.class.getDeclaredField("num");
System.out.println(field); // public int A.num

final var ret1 = field.getDeclaredAnnotation(Foo.class);
System.out.println(ret1.annotationType().getSimpleName()); // Foo

final var ret2 = field.getDeclaredAnnotation(Bar.class);
System.out.println(ret2); // null
final AccessibleObject method = A.class.getDeclaredMethod("aaa");
System.out.println(method); // public void A.aaa()

final var ret1 = method.getDeclaredAnnotation(Foo.class);
System.out.println(ret1); // null

final var ret2 = method.getDeclaredAnnotation(Bar.class);
System.out.println(ret2.annotationType().getSimpleName()); // Bar

Annotation[] getDeclaredAnnotations ()

Returns annotations that are directly present on this element.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Foo {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Bar {
}

public class A {
    @Foo
    @Bar
    public int num;
}
final var accessibleObject = A.class.getDeclaredField("num");
System.out.println(accessibleObject);

System.out.println("-- annotations --");
for (final var a : accessibleObject.getDeclaredAnnotations()) {
    System.out.println(a.annotationType().getSimpleName());
}

// Result
// ↓
//public int A.num
//-- annotations --
//Foo
//Bar

<T extends Annotation> T[] getDeclaredAnnotationsByType (Class<T> annotationClass)

Returns this element's annotation(s) for the specified type if such annotations are either directly present or indirectly present.

@Repeatable(FooArray.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Foo {
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FooArray {
    Foo[] value();
}

public class A {
    @Foo("a1")
    @Foo("a2")
    public int num;
}
final AccessibleObject accessibleObject = A.class.getDeclaredField("num");
System.out.println(accessibleObject);

System.out.println("-- annotations --");
for (final var a : accessibleObject.getDeclaredAnnotationsByType(Foo.class)) {
    System.out.println(a.annotationType().getSimpleName() + " : " + a.value());
}

// Result
// ↓
//public int A.num
//-- annotations --
//Foo : a1
//Foo : a2

boolean isAccessible ()

Deprecated. This method is deprecated because its name hints that it checks if the reflected object is accessible when it actually indicates if the checks for Java language access control are suppressed.

Deprecated.

boolean isAnnotationPresent (Class<? extends Annotation> annotationClass)

Returns true if an annotation for the specified type is present on this element, else false.

Please see getAnnotation(Class<T> annotationClass).

void setAccessible (boolean flag)

Set the accessible flag for this reflected object to the indicated boolean value.

public class AccessTest {
    private int num = 100;
}
final AccessibleObject accessibleObject = AccessTest.class.getDeclaredField("num");
final var obj = new AccessTest();

System.out.println(accessibleObject.canAccess(obj)); // false

accessibleObject.setAccessible(true);
System.out.println(accessibleObject.canAccess(obj)); // true

accessibleObject.setAccessible(false);
System.out.println(accessibleObject.canAccess(obj)); // false

static void setAccessible (AccessibleObject[] array, boolean flag)

Convenience method to set the accessible flag for an array of reflected objects with a single security check (for efficiency).

public class AccessTest2 {
    private int num = 100;
    private String str = "abcd";
}
final var cls = AccessTest2.class;

final AccessibleObject[] array = {
        cls.getDeclaredField("num"),
        cls.getDeclaredField("str")
};

System.out.println("-- AccessibleObject --");
for (final var accessibleObject : array) {
    System.out.println(accessibleObject);
}

final var obj = new AccessTest2();

System.out.println("-- canAccess --");
for (final var accessibleObject : array) {
    System.out.println(accessibleObject.canAccess(obj));
}

AccessibleObject.setAccessible(array, true);

System.out.println("-- canAccess --");
for (final var accessibleObject : array) {
    System.out.println(accessibleObject.canAccess(obj));
}

AccessibleObject.setAccessible(array, false);

System.out.println("-- canAccess --");
for (final var accessibleObject : array) {
    System.out.println(accessibleObject.canAccess(obj));
}

// Result
// ↓
//-- AccessibleObject --
//private int AccessTest2.num
//private java.lang.String AccessTest2.str
//-- canAccess --
//false
//false
//-- canAccess --
//true
//true
//-- canAccess --
//false
//false

final boolean trySetAccessible ()

Set the accessible flag for this reflected object to true if possible.

Please see canAccess(Object obj).


Related posts

To top of page