如题,定义了一个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的属性并没有被包含在Method的equals 和hashCode中
拉莫斯之舞
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;
}
狐的传说
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);//正常
我能想到的解释是: test1 和 test2 的引用不是一个,但是equals和hashcode又是一样的,让我也迷惑了.但解释应该还是我想到但那样,他们但引用是不相同的
添加回答
举报
0/150
提交
取消
