为了账号安全,请及时绑定邮箱和手机立即绑定

java反射使用setAccessible(true)调用private方法问题

java反射使用setAccessible(true)调用private方法问题

隔江千里 2019-05-10 09:18:52
如题,定义了一个Person类有一个private方法publicPerson{privatevoidtest();//private方法}使用反射来调用先说有问题的方法Constructorcon=Person.class.getConstructor();//构造方法Objectobject=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注解,是这个原因吗?望解答。
查看完整描述

2 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

每次获取方法得到不是同一个Method对象setAccessable仅作用于得到的方法对象,也不是全局的所以第一种写法会报错
另外,setAccessable的属性并没有被包含在Method的equals和hashCode中
                            
查看完整回答
反对 回复 2019-05-10
?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

@CallerSensitive
publicMethodgetDeclaredMethod(Stringname,Class...parameterTypes)
throwsNoSuchMethodException,SecurityException{
checkMemberAccess(Member.DECLARED,Reflection.getCallerClass(),true);
Methodmethod=searchMethods(privateGetDeclaredMethods(false),name,parameterTypes);
if(method==null){
thrownewNoSuchMethodException(getName()+"."+name+argumentTypesToString(parameterTypes));
}
returnmethod;
}
privatestaticMethodsearchMethods(Method[]methods,
Stringname,
Class[]parameterTypes)
{
Methodres=null;
StringinternedName=name.intern();
for(inti=0;iMethodm=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-privateroutine(exposedtojava.lang.Classvia
*ReflectAccess)whichreturnsacopyofthisMethod.Thecopy's
*"root"fieldpointstothisMethod.
*/
Methodcopy(){
//ThisroutineenablessharingofMethodAccessorobjects
//amongMethodobjectswhichrefertothesameunderlying
//methodintheVM.(Allofthiscontortionisonlynecessary
//becauseofthe"accessibility"bitinAccessibleObject,
//whichimplicitlyrequiresthatnewjava.lang.reflect
//objectsbefabricatedforeachreflectivecallonClass
//objects.)
if(this.root!=null)
thrownewIllegalArgumentException("Cannotcopyanon-rootMethod");
//注意这里,意味着每次调用都会new一个Method对象
Methodres=newMethod(clazz,name,parameterTypes,returnType,
exceptionTypes,modifiers,slot,signature,
annotations,parameterAnnotations,annotationDefault);
res.root=this;
//Mightaswelleagerlypropagatethisifalreadypresent
res.methodAccessor=methodAccessor;
returnres;
}
                            
查看完整回答
反对 回复 2019-05-10
  • 2 回答
  • 0 关注
  • 1939 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信