java基础源码 (5)--reflect包-AccessibleObject类

学习参考博客:https://blog.csdn.net/benjaminzhang666/article/details/9664585
AccessibleObject类基本作用
  1。将反射的对象标记为在使用时取消默认java语言访问控制检查的能力
  2。在反射对象中设置accessible(翻译:无障碍)标志允许具有足够的特权
/**
 * The AccessibleObject class is the base class for Field, Method and
 * Constructor objects.  It provides the ability to flag a reflected
 * object as suppressing default Java language access control checks
 * when it is used.  The access checks--for public, default (package)
 * access, protected, and private members--are performed when Fields,
 * Methods or Constructors are used to set or get fields, to invoke
 * methods, or to create and initialize new instances of classes,
 * respectively.
  AccessibleObject类是Field,Method和Constructor对象的父类,它提供了将反射对象标记
为在使用它时抑制默认java语言访问控制检查的功能。当使用Fields,Methods或Constructor来
设置或获取字段,调用方法,或创建和初始化新的类实例时,执行访问检查(对于public,默认(包)访问
,受保护和私有成员) * * <p>Setting the {
@code accessible} flag in a reflected object * permits sophisticated applications with sufficient privilege, such * as Java Object Serialization or other persistence mechanisms, to * manipulate objects in a manner that would normally be prohibited. 在反射对象中设置accessible标志允许具有足够权限的复杂应用程序(如java对象序列化
或其他持久性机制)以通常被禁止的方式操纵对象 * <p>By default, a reflected object is <em>not</em> accessible.
  默认情况下,反射对象不可访问
*/ public class AccessibleObject implements AnnotatedElement { /** * The Permission object that is used to check whether a client * has sufficient privilege to defeat Java language access * control checks.
    Permission对象,用于检查客户端是否具有足够的权限来阻止java语言访问控制检查
*/ static final private java.security.Permission ACCESS_PERMISSION = new ReflectPermission("suppressAccessChecks"); /** * Convenience method to set the {@code accessible} flag for an * array of objects with a single security check (for efficiency).     使用单一安全检查来设置对象数组的可访问标志的一个方便的方法(为了效率)*/ public static void setAccessible(AccessibleObject[] array, boolean flag) throws SecurityException { SecurityManager sm = System.getSecurityManager();//获取系统安全的接口 if (sm != null) sm.checkPermission(ACCESS_PERMISSION); for (int i = 0; i < array.length; i++) { setAccessible0(array[i], flag); } } /**   将对象的可访问标志设置为指示的布尔值*/ public void setAccessible(boolean flag) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(ACCESS_PERMISSION); setAccessible0(this, flag); } /* Check that you aren't exposing java.lang.Class.<init> or sensitive fields in java.lang.Class. */ private static void setAccessible0(AccessibleObject obj, boolean flag) throws SecurityException { if (obj instanceof Constructor && flag == true) { Constructor<?> c = (Constructor<?>)obj; if (c.getDeclaringClass() == Class.class) { throw new SecurityException("Cannot make a java.lang.Class" + " constructor accessible"); } } obj.override = flag; } /**    获取此对象的accessible标志的值(布尔类型)*/ public boolean isAccessible() { return override; } /** * Constructor: only used by the Java Virtual Machine.
    构造函数,仅有java虚拟机使用
*/ protected AccessibleObject() {} // Indicates whether language-level access checks are overridden // by this object. Initializes to "false". This field is used by // Field, Method, and Constructor. 通过这个对象,指示是否覆盖语言级别访问检查权限,初始化为false,该字段用于Field,
  Method和Constructor
// NOTE: for security purposes, this field must not be visible // outside this package.
  出于安全考虑,此字段不得显示出包外
boolean override; // Reflection factory used by subclasses for creating field, // method, and constructor accessors. Note that this is called // very early in the bootstrapping process.
    子类用于创建字段,方法和构造函数的反射工厂
static final ReflectionFactory reflectionFactory = AccessController.doPrivileged( new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); /** * @throws NullPointerException {@inheritDoc} * @since 1.5 */ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { throw new AssertionError("All subclasses should override this method"); } /** * {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @since 1.5 */ @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return AnnotatedElement.super.isAnnotationPresent(annotationClass); } /** * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @Override public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { throw new AssertionError("All subclasses should override this method"); } /** * @since 1.5 */ public Annotation[] getAnnotations() { return getDeclaredAnnotations(); } /** * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @Override public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { // Only annotations on classes are inherited, for all other // objects getDeclaredAnnotation is the same as // getAnnotation. return getAnnotation(annotationClass); } /** * @throws NullPointerException {@inheritDoc} * @since 1.8 */ @Override public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { // Only annotations on classes are inherited, for all other // objects getDeclaredAnnotationsByType is the same as // getAnnotationsByType. return getAnnotationsByType(annotationClass); } /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { throw new AssertionError("All subclasses should override this method"); } // Shared access checking logic. // For non-public members or members in package-private classes, // it is necessary to perform somewhat expensive security checks. // If the security check succeeds for a given class, it will // always succeed (it is not affected by the granting or revoking // of permissions); we speed up the check in the common case by // remembering the last Class for which the check succeeded. // // The simple security check for Constructor is to see if // the caller has already been seen, verified, and cached. // (See also Class.newInstance(), which uses a similar method.) // // A more complicated security check cache is needed for Method and Field // The cache can be either null (empty cache), a 2-array of {caller,target}, // or a caller (with target implicitly equal to this.clazz). // In the 2-array case, the target is always different from the clazz. volatile Object securityCheckCache; void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers) throws IllegalAccessException { if (caller == clazz) { // quick check return; // ACCESS IS OK } Object cache = securityCheckCache; // read volatile Class<?> targetClass = clazz; if (obj != null && Modifier.isProtected(modifiers) && ((targetClass = obj.getClass()) != clazz)) { // Must match a 2-list of { caller, targetClass }. if (cache instanceof Class[]) { Class<?>[] cache2 = (Class<?>[]) cache; if (cache2[1] == targetClass && cache2[0] == caller) { return; // ACCESS IS OK } // (Test cache[1] first since range check for [1] // subsumes range check for [0].) } } else if (cache == caller) { // Non-protected case (or obj.class == this.clazz). return; // ACCESS IS OK } // If no return, fall through to the slow path. slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass); } // Keep all this slow stuff out of line: void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers, Class<?> targetClass) throws IllegalAccessException { Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); // Success: Update the cache. Object cache = ((targetClass == clazz) ? caller : new Class<?>[] { caller, targetClass }); // Note: The two cache elements are not volatile, // but they are effectively final. The Java memory model // guarantees that the initializing stores for the cache // elements will occur before the volatile write. securityCheckCache = cache; // write volatile } }
原文地址:https://www.cnblogs.com/lkeji388/p/9545115.html