Java : AccessibleObject - API使用例
AccessibleObject (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
AccessibleObject を使うと、例えば private なフィールドにも動的にアクセスできるようになります。
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
コンストラクタ
AccessibleObject ()
非推奨です。
メソッド
final boolean canAccess (Object obj)
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)
@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 ()
@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());
}
// 結果
// ↓
//public int A.num
//-- annotations --
//Foo
//Bar
<T extends Annotation> T[] getAnnotationsByType (Class<T> annotationClass)
@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());
}
// 結果
// ↓
//public int A.num
//-- annotations --
//Foo : a1
//Foo : a2
<T extends Annotation> T getDeclaredAnnotation (Class<T> annotationClass)
@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 ()
@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());
}
// 結果
// ↓
//public int A.num
//-- annotations --
//Foo
//Bar
<T extends Annotation> T[] getDeclaredAnnotationsByType (Class<T> annotationClass)
@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());
}
// 結果
// ↓
//public int A.num
//-- annotations --
//Foo : a1
//Foo : a2
boolean isAccessible ()
非推奨です。
boolean isAnnotationPresent (Class<? extends Annotation> annotationClass)
このメソッドの使用例は、getAnnotation(Class<T> annotationClass) にまとめて記載しました。
そちらのAPI使用例をご参照ください。
void setAccessible (boolean flag)
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)
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));
}
// 結果
// ↓
//-- AccessibleObject --
//private int AccessTest2.num
//private java.lang.String AccessTest2.str
//-- canAccess --
//false
//false
//-- canAccess --
//true
//true
//-- canAccess --
//false
//false
final boolean trySetAccessible ()
このメソッドの使用例は、canAccess(Object obj) にまとめて記載しました。
そちらのAPI使用例をご参照ください。