Java反射 Field类的setAccessible() 方法「建议收藏」

Java反射 Field类的setAccessible() 方法「建议收藏」首先看看源码:/***Setthe{@codeaccessible}flagforthisobjectto*theindicatedbooleanvalue.Avalueof{@codetrue}indicatesthat*thereflectedobjectshouldsuppressJavalan…

大家好,欢迎来到IT知识分享网。

首先看看源码:

/**
     * Set the {@code accessible} flag for this object to
     * the indicated boolean value.  A value of {@code true} indicates that
     * the reflected object should suppress Java language access
     * checking when it is used.  A value of {@code false} indicates
     * that the reflected object should enforce Java language access checks.
     *
     * <p>First, if there is a security manager, its
     * {@code checkPermission} method is called with a
     * {@code ReflectPermission("suppressAccessChecks")} permission.
     *
     * <p>A {@code SecurityException} is raised if {@code flag} is
     * {@code true} but accessibility of this object may not be changed
     * (for example, if this element object is a {@link Constructor} object for
     * the class {@link java.lang.Class}).
     *
     * <p>A {@code SecurityException} is raised if this object is a {@link
     * java.lang.reflect.Constructor} object for the class
     * {@code java.lang.Class}, and {@code flag} is true.
     *
     * @param flag the new value for the {@code accessible} flag
     * @throws SecurityException if the request is denied.
     * @see SecurityManager#checkPermission
     * @see java.lang.RuntimePermission
     */
    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;
    }

    /**
     * Get the value of the {@code accessible} flag for this object.
     *
     * @return the value of the object's {@code accessible} flag
     */
    public boolean isAccessible() {
        return override;
    }

通过源码发现:

1.注释说是 是否对反射的对象进行Java语言访问检查【那就是和 访问权限控制符有关了】

2.内部函数setAccessible0()中,说明obj是Constructor的对象,并且flag为true时才能强制转换什么的。嗯,先记下这个线索。

3.setAccessible()对应有一个函数 isAccessible()返回的,就是我们保存的布尔值flag。

通过简单测试,使用四个访问权限控制符修饰的属性调用 isAccessible()函数,得出:

private's   isAccessible = false
default's   isAccessible = false
public's    isAccessible = false
protected's isAccessible = false

额,没有特殊的限制~

使用field的各个内部方法,四个访问权限.getName() .getType()等等都没有抛出异常~

难道发现Java lang的bug呢?想一想,嗯,还有线索2没有使用。

于是尝试与构造函数相关的get(Object obj) 和 set(Object obj, Object value)。

只有:private修饰的属性果然抛出了异常:

Exception in thread "main" java.lang.IllegalAccessException: Class ObjectTest.TestFile.test02 can not access a member of class ObjectTest.TestFile.A with modifiers "private"

将此属性调用方法:.setAccessible(true); 异常解决了。

 

所以可以得出结论:

当isAccessible()的结果是false时,如果该字段是private修饰的,不允许通过反射访问该字段 ;必须要改成true才可以访问 。

.setAccessible(true);的作用就是: 在用反射时可以访问私有变量!

 

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/24682.html

(0)
上一篇 2023-08-15 18:33
下一篇 2023-08-17 09:00

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信