亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

java反射使用setAccessible(true)調用private方法問題

java反射使用setAccessible(true)調用private方法問題

慕田峪7331174 2019-01-16 09:12:46
如題,定義了一個Person類有一個private方法 public Person { private void test();//private方法 } 使用反射來調用先說有問題的方法 Constructor con= Person.class.getConstructor();//構造方法 Object object = con.newInstance();//生成對象 //有問題 Person.class.getDeclareMethod("test").setAccessible(true); Person.class.getDeclareMethod("test").invoke(object);//報錯不能訪問 /*Person.class.getDeclareMethod("test").isAccessible()還是等于false*/ 而使用下面的寫法卻可以 Method = Person.class.getDeclareMethod("test"); method.setAccessible(true); method.invoke(object);//不報錯,正常執行 /*method.isAccessible()是true 而Person.class.getDeclareMethod("test").isAccessible()還是等于false */ 這是Person.class.getDeclareMethod("test")方法的問題嗎,這個問題在反射調用構造函數時也會出現,他們都有一個@CallerSensitive注解,是這個原因嗎?望解答。
查看完整描述

3 回答

?
qq_遁去的一_1

TA貢獻1725條經驗 獲得超8個贊

每次獲取方法得到不是同一個Method對象
setAccessable僅作用于得到的方法對象,也不是全局的
所以第一種寫法會報錯

另外,setAccessable的屬性并沒有被包含在MethodequalshashCode

查看完整回答
反對 回復 2019-02-12
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
    throws NoSuchMethodException, SecurityException {
    checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
    Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
    if (method == null) {
        throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
    }
    return method;
}
private static Method searchMethods(Method[] methods,
                                        String name,
                                        Class<?>[] parameterTypes)
    {
        Method res = null;
        String internedName = name.intern();
        for (int i = 0; i < methods.length; i++) {
            Method m = methods[i];
            if (m.getName() == internedName
                && arrayContentsEq(parameterTypes, m.getParameterTypes())
                && (res == null
                    || res.getReturnType().isAssignableFrom(m.getReturnType())))
                res = m;
        }

        return (res == null ? res : getReflectionFactory().copyMethod(res));
    }

...
到最后,其實是:

/**
 * Package-private routine (exposed to java.lang.Class via
 * ReflectAccess) which returns a copy of this Method. The copy's
 * "root" field points to this Method.
 */
Method copy() {
    // This routine enables sharing of MethodAccessor objects
    // among Method objects which refer to the same underlying
    // method in the VM. (All of this contortion is only necessary
    // because of the "accessibility" bit in AccessibleObject,
    // which implicitly requires that new java.lang.reflect
    // objects be fabricated for each reflective call on Class
    // objects.)
    if (this.root != null)
        throw new IllegalArgumentException("Can not copy a non-root Method");
    // 注意這里,意味著每次調用都會new一個Method對象
    Method res = new Method(clazz, name, parameterTypes, returnType,
                            exceptionTypes, modifiers, slot, signature,
                            annotations, parameterAnnotations, annotationDefault);
    res.root = this;
    // Might as well eagerly propagate this if already present
    res.methodAccessor = methodAccessor;
    return res;
}
查看完整回答
反對 回復 2019-02-12
?
狐的傳說

TA貢獻1804條經驗 獲得超3個贊

以前我還真沒有注意到這個問題,我幫你驗證了一下.

        Constructor con = People.class.getConstructor();//構造方法
        Object object = con.newInstance();//生成對象
        Method test1 = People.class.getDeclaredMethod("test");
        test1.setAccessible(true);

        Method test2 = People.class.getDeclaredMethod("test");
        
        System.out.println(test1.hashCode());//一樣的hashcode
        System.out.println(test2.hashCode());//一樣的hashcode

        test1.invoke(object);//正常

我能想到的解釋是: test1test2 的引用不是一個,但是equals和hashcode又是一樣的,讓我也迷惑了.但解釋應該還是我想到但那樣,他們但引用是不相同的

查看完整回答
反對 回復 2019-02-12
  • 3 回答
  • 0 關注
  • 890 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號