模块 java.base

类 AccessibleObject

java.lang.Object
java.lang.reflect.AccessibleObject
所有已实现的接口:
AnnotatedElement
已知子类:
Executable , Field

public class AccessibleObject extends Object implements AnnotatedElement
AccessibleObject 类是 FieldMethodConstructor 对象(称为 reflected objects)的基类。它提供了将反射对象标记为在使用时抑制对 Java 语言访问控制的检查的能力。这允许具有足够权限的复杂应用程序(例如 Java 对象序列化或其他持久性机制)以通常被禁止的方式操作对象。

Java 语言访问控制防止在其顶级类之外使用私有成员;包访问包外的成员;在其包或子类之外的受保护成员;和模块外的公共成员,除非它们在 exported 包和用户 reads 他们的模块中声明。默认情况下,当 Field s、Method s 或 Constructor s 分别用于获取或设置字段、调用方法或创建和初始化类的新实例时,将强制执行 Java 语言访问控制(有一种变体)。每个反射对象都会检查使用它的代码是否在适当的类、包或模块中。由 JNI代码 调用且堆栈上没有 Java 类的检查只有在成员和声明类是公共的并且该类位于导出到所有模块的包中时才会成功。

Java 语言访问控制的一个变体是反射对象的检查假定可读性。也就是说,假定包含使用反射对象的模块读取声明了基础字段、方法或构造方法的模块。

是否可以抑制对 Java 语言访问控制的检查(以及是否可以启用访问)取决于反射的对象是否对应于导出包或打开包中的成员(请参阅 setAccessible(boolean) )。

Java 语言规范:
6.6 访问控制
自从:
1.2
  • 构造方法详细信息

    • AccessibleObject

      @Deprecated (since ="17") protected AccessibleObject()
      已弃用。
      构造方法:仅供 Java 虚拟机使用。
  • 方法详情

    • setAccessible

      public static void setAccessible(AccessibleObject [] array, boolean flag)
      使用单个安全检查(为了提高效率)为反射对象数组设置 accessible 标志的便捷方法。

      当可以按照 setAccessible(boolean) 的指定启用对每个反射对象的访问时,此方法可用于启用对数组中所有反射对象的访问。

      如果有安全管理器,它的 checkPermission 方法将首先以 ReflectPermission("suppressAccessChecks") 权限调用。

      如果输入 array 的任何元素是类 java.lang.ClassConstructor 对象且 flag 为真,也会抛出 SecurityException

      参数:
      array - AccessibleObjects 数组
      flag - 每个对象中 accessible 标志的新值
      抛出:
      InaccessibleObjectException - 如果无法为数组中的所有对象启用访问
      SecurityException - 如果请求被安全管理器拒绝或数组中的元素是 java.lang.Class 的构造函数
      参见:
    • setAccessible

      public void setAccessible(boolean flag)
      将此反射对象的 accessible 标志设置为指示的boolean。值 true 表示反射对象在使用时应禁止检查 Java 语言访问控制。值 false 表示反射对象在使用时应强制检查 Java 语言访问控制,并在类描述中注明变化。

      如果以下任何一项成立,则类 C 中的调用者可以使用此方法来启用对 declaring class Dmember 的访问:

      • CD 在同一模块中。
      • 成员是 publicDpublic 在一个包中,模块包含 D exports 到至少包含 C 的模块。
      • 成员是 protected staticD 是包中的 public,包含 D 的模块导出到至少包含 C 的模块,而 CD 的子类。
      • D 在包含 D opens 的模块到至少包含 C 的模块的包中。未命名和开放模块中的所有包都对所有模块开放,因此当 D 在未命名或开放模块中时,此方法总是成功。

      当且仅当:

      • 成员是publicDpublic,模块无条件包含D exports

      当声明类与调用者位于不同的模块中并且包含声明类的包未向其开放时,此方法不能用于启用对私有成员、具有默认(包)访问权限的成员、受保护实例成员或受保护构造方法的访问调用者的模块。

      此方法不能用于启用 write non-modifiable final 字段的访问。以下字段是不可修改的:

      • 在任何类或接口中声明的静态最终字段
      • 隐藏类 中声明的最终字段
      • 记录 中声明的最终字段

      true 时的 accessible 标志抑制 Java 语言访问控制检查以仅启用 read 对这些不可修改的最终字段的访问。

      如果有安全管理器,它的 checkPermission 方法将首先以 ReflectPermission("suppressAccessChecks") 权限调用。

      参数:
      flag - accessible 标志的新值
      抛出:
      InaccessibleObjectException - 如果无法启用访问
      SecurityException - 如果请求被安全管理器拒绝
      参见:
    • trySetAccessible

      public final boolean trySetAccessible()
      如果可能,将此反射对象的 accessible 标志设置为 true。此方法设置 accessible 标志,就像通过调用 setAccessible(true) 一样,并返回 accessible 标志的可能更新值。如果无法启用访问,即无法抑制检查或 Java 语言访问控制,则此方法返回 false(与 setAccessible(true) 失败时抛出 InaccessibleObjectException 相反)。

      如果此反射对象的 accessible 标志为 true,则此方法为空操作。

      例如,调用者可以在 Method 对象上为私有实例方法 p.T::privateMethod 调用 trySetAccessible,以在调用 Method 时抑制对 Java 语言访问控制的检查。如果 p.T 类与调用者在不同的模块中,并且包 p 至少对调用者的模块开放,则下面的代码成功地将 accessible 标志设置为 true

       
         p.T obj = ....; // instance of p.T
         :
         Method m = p.T.class.getDeclaredMethod("privateMethod");
         if (m.trySetAccessible()) {
           m.invoke(obj);
         } else {
           // package p is not opened to the caller to access private member of T
           ...
         }
        

      如果此方法由 JNI代码 调用且堆栈上没有调用者类,则只有在成员和声明类是公共的并且该类位于无条件导出的包中时才能设置 accessible 标志。

      如果有安全管理器,它的 checkPermission 方法将首先以 ReflectPermission("suppressAccessChecks") 权限调用。

      返回:
      true 如果 accessible 标志设置为 truefalse 如果无法启用访问。
      抛出:
      SecurityException - 如果请求被安全管理器拒绝
      自从:
      9
      参见:
    • isAccessible

      @Deprecated (since ="9") public boolean isAccessible()
      已弃用。
      此方法已被弃用,因为它的名称暗示它检查反射对象是否可访问,而实际上它指示是否抑制了对 Java 语言访问控制的检查。此方法可能会在调用者可访问的反射对象上返回 false。要测试此反射对象是否可访问,应使用 canAccess(Object)
      获取此反射对象的 accessible 标志的值。
      返回:
      对象的 accessible 标志的值
    • canAccess

      public final boolean canAccess(Object  obj)
      测试调用者是否可以访问此反射对象。如果此反射对象对应于实例方法或字段,则此方法测试调用者是否可以使用反射对象访问给定的obj。对于实例方法或字段,obj 参数必须是 declaring class 的实例。对于静态成员和构造函数,obj 必须是 null

      如果 accessible 标志设置为 true ,即抑制对 Java 语言访问控制的检查,或者如果调用者可以访问中指定的成员,则此方法返回 trueJava 语言规范,在类描述中注明了变化。如果此方法由 JNI代码 调用且堆栈上没有调用者类,则此方法返回 true 如果成员和声明类是公共的,并且该类位于无条件导出的包中。

      参数:
      obj - 如果它是实例方法或字段,则此反射对象的声明类的实例对象
      返回:
      true 如果调用者可以访问此反射对象。
      抛出:
      IllegalArgumentException -
      • 如果此反射对象是静态成员或构造函数并且给定的 obj 是非 null ,或者
      • 如果此反射对象是实例方法或字段,并且给定的 objnull 或类型不是成员的 declaring class 的子类。
      Java 语言规范:
      6.6 访问控制
      自从:
      9
      参见:
    • getAnnotation

      public <T extends Annotation > T getAnnotation(Class <T> annotationClass)
      如果此类注解为 present ,则返回此元素针对指定类型的注解,否则为 null。

      请注意,此方法返回的任何注解都是声明注解。

      指定者:
      getAnnotation 在接口 AnnotatedElement
      实现要求:
      默认实现抛出 UnsupportedOperationException ;子类应该覆盖这个方法。
      类型参数:
      T - 要查询并返回的注释类型(如果存在)
      参数:
      annotationClass——注解类型对应的Class对象
      返回:
      如果此元素上存在此元素的指定注解类型的注解,则为 null
      抛出:
      NullPointerException - 如果给定的注释类为 null
      自从:
      1.5
    • isAnnotationPresent

      public boolean isAnnotationPresent(Class <? extends Annotation > annotationClass)
      如果指定类型的注解在此元素上为 present,则返回 true,否则返回 false。此方法主要是为了方便访问标记注释而设计的。

      该方法返回的真值相当于:getAnnotation(annotationClass) != null

      指定者:
      isAnnotationPresent 在接口 AnnotatedElement
      参数:
      annotationClass——注解类型对应的Class对象
      返回:
      如果此元素上存在指定注解类型的注解,则为 true,否则为 false
      抛出:
      NullPointerException - 如果给定的注释类为 null
      自从:
      1.5
    • getAnnotationsByType

      public <T extends Annotation > T[] getAnnotationsByType(Class <T> annotationClass)
      返回带有此元素的 associated 注释。如果这个元素没有注解associated,返回值是一个长度为0的数组。这个方法和AnnotatedElement.getAnnotation(Class) 的区别是这个方法检测它的参数是否是一个repeatable annotation type(JLS 9.6),如果是,则尝试寻找通过“查看”容器注解来查看该类型的一个或多个注释。该方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

      请注意,此方法返回的任何注释都是声明注解。

      指定者:
      getAnnotationsByType 在接口 AnnotatedElement
      实现要求:
      默认实现抛出 UnsupportedOperationException ;子类应该覆盖这个方法。
      类型参数:
      T - 要查询并返回的注释类型(如果存在)
      参数:
      annotationClass——注解类型对应的Class对象
      返回:
      如果与此元素相关联,则为指定注解类型的所有此元素的注释,否则为长度为零的数组
      抛出:
      NullPointerException - 如果给定的注释类为 null
      自从:
      1.8
    • getAnnotations

      public Annotation [] getAnnotations()
      返回此元素上的 present 注释。如果该元素上没有注解present,则返回值为长度为0的数组。该方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

      请注意,此方法返回的任何注释都是声明注解。

      指定者:
      getAnnotations 在接口 AnnotatedElement
      返回:
      此元素上的注释
      自从:
      1.5
    • getDeclaredAnnotation

      public <T extends Annotation > T getDeclaredAnnotation(Class <T> annotationClass)
      如果此类注解为 directly present ,则返回此元素针对指定类型的注解,否则为 null。此方法忽略继承的注释。 (如果没有注释直接出现在该元素上,则返回 null。)

      请注意,此方法返回的任何注解都是声明注解。

      指定者:
      getDeclaredAnnotation 在接口 AnnotatedElement
      类型参数:
      T - 如果直接存在则查询并返回的注解类型
      参数:
      annotationClass——注解类型对应的Class对象
      返回:
      如果直接出现在此元素上,则此元素针对指定注解类型的注解,否则为 null
      抛出:
      NullPointerException - 如果给定的注释类为 null
      自从:
      1.8
    • getDeclaredAnnotationsByType

      public <T extends Annotation > T[] getDeclaredAnnotationsByType(Class <T> annotationClass)
      如果此类注解是 directly presentindirectly present ,则返回此元素的指定类型的注解。此方法忽略继承的注释。如果没有指定的注解直接或间接出现在这个元素上,返回值是一个长度为0的数组。这个方法和AnnotatedElement.getDeclaredAnnotation(Class) 的区别是这个方法检测它的参数是否是一个repeatable annotation type(JLS 9.6),如果是,尝试通过“查看”容器注解(如果存在)来查找该类型的一个或多个注释。该方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

      请注意,此方法返回的任何注释都是声明注解。

      指定者:
      getDeclaredAnnotationsByType 在接口 AnnotatedElement
      类型参数:
      T - 如果直接或间接存在,要查询并返回的注释类型
      参数:
      annotationClass——注解类型对应的Class对象
      返回:
      如果直接或间接出现在该元素上,则指定注解类型的所有该元素的注释,否则为长度为零的数组
      抛出:
      NullPointerException - 如果给定的注释类为 null
      自从:
      1.8
    • getDeclaredAnnotations

      public Annotation [] getDeclaredAnnotations()
      返回此元素上的 directly present 注释。此方法忽略继承的注释。如果该元素上没有注解directly present,则返回值为长度为0的数组。该方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。

      请注意,此方法返回的任何注释都是声明注解。

      指定者:
      getDeclaredAnnotations 在接口 AnnotatedElement
      实现要求:
      默认实现抛出 UnsupportedOperationException ;子类应该覆盖这个方法。
      返回:
      注释直接出现在这个元素上
      自从:
      1.5