如题,定义了一个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中
料青山看我应如是
TA贡献1772条经验 获得超8个赞
@CallerSensitivepublicMethodgetDeclaredMethod(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;//Mightaswelleagerlypropagatethisifalreadypresentres.methodAccessor=methodAccessor;returnres;}
添加回答
举报
0/150
提交
取消