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

qq_遁去的一_1
TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個(gè)贊
每次獲取方法得到不是同一個(gè)Method
對象 setAccessable
僅作用于得到的方法對象,也不是全局的
所以第一種寫法會報(bào)錯(cuò)
另外,setAccessable
的屬性并沒有被包含在Method
的equals
和hashCode
中

拉莫斯之舞
TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超10個(gè)贊
@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));
}
...
到最后,其實(shí)是:
/**
* 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");
// 注意這里,意味著每次調(diào)用都會new一個(gè)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;
}

狐的傳說
TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超3個(gè)贊
以前我還真沒有注意到這個(gè)問題,我?guī)湍泸?yàn)證了一下.
Constructor con = People.class.getConstructor();//構(gòu)造方法
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);//正常
我能想到的解釋是: test1
和 test2
的引用不是一個(gè),但是equals和hashcode又是一樣的,讓我也迷惑了.但解釋應(yīng)該還是我想到但那樣,他們但引用是不相同的
添加回答
舉報(bào)
0/150
提交
取消