Any way to Invoke a private method?
You can invoke private method with reflection. Modifying the last bit of the posted code:
Method method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);
There are a couple of caveats. First, getDeclaredMethod
will only find method declared in the current Class
, not inherited from supertypes. So, traverse up the concrete class hierarchy if necessary. Second, a SecurityManager
can prevent use of the setAccessible
method. So, it may need to run as a PrivilegedAction
(using AccessController
or Subject
).
How do I use reflection to access a private method?
getDeclaredMethod
needs you to pass the parameter types so that it can resolve overloaded methods.
Since your foo
method has a single parameter of type String
, the following should work:
Method m = Dummy.class.getDeclaredMethod("foo", String.class);
And of course you also need to change the invoke
call to pass a string.
How do I use reflection to invoke a private method?
Simply change your code to use the overloaded version of GetMethod
that accepts BindingFlags:
MethodInfo dynMethod = this.GetType().GetMethod("Draw_" + itemType,
BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod.Invoke(this, new object[] { methodParams });
Here's the BindingFlags enumeration documentation.
How to invoke private method via Reflection when parameter of method is List?
There are two problems in your code
- you are using
getMethod
which can only returnpublic
methods, to get private ones usegetDeclaredMethod
on type which declares it. - you are invoking your method on
"method"
String literal instead of instance ofA
class (String doesn't have this method, so you can't invoke it on its instance. For now your code is equivalent to something like"method".method(yourList)
which is not correct).
Your code should look like
Class<A> clazz = A.class;
Method met = clazz.getDeclaredMethod("method", List.class);
// ^^^^^^^^
met.setAccessible(true);
String res = (String) met.invoke(new A(), new ArrayList<Integer>());
// ^^^^^^^
//OR pass already existing instance of A class
//A myA = new A(); //other instance of A on which you want to call the method
//...
//String res = (String) met.invoke(myA, new ArrayList<Integer>());
System.out.println(res);
Invoke private method in arbitrary scala object
Try the following if you have String
of object name
def invokeObjectPrivateMethod[R](objectName: String, methodName: String, args: AnyRef*): R = {
val rm = scala.reflect.runtime.currentMirror
val moduleSymbol = rm.staticModule(objectName)
val classSymbol = moduleSymbol.moduleClass.asClass
val moduleMirror = rm.reflectModule(moduleSymbol)
val objectInstance = moduleMirror.instance
val objectType = classSymbol.toType
val methodSymbol = objectType.decl(ru.TermName(methodName)).asMethod
val instanceMirror = rm.reflect(objectInstance)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(args: _*).asInstanceOf[R]
}
invokeObjectPrivateMethod("com.example.App.SomeObject", "someMethod", "it works") //it works
or if you have object ClassTag
def invokeObjectPrivateMethod[R](classTag: ClassTag[_], methodName: String, args: AnyRef*): R = {
val rm = scala.reflect.runtime.currentMirror
val clazz = classTag.runtimeClass
val classSymbol = rm.classSymbol(clazz)
val moduleSymbol = classSymbol.owner.info.decl(classSymbol.name.toTermName).asModule //see (*)
val moduleMirror = rm.reflectModule(moduleSymbol)
val objectInstance = moduleMirror.instance
val objectType = classSymbol.toType
val methodSymbol = objectType.decl(ru.TermName(methodName)).asMethod
val instanceMirror = rm.reflect(objectInstance)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(args: _*).asInstanceOf[R]
}
invokeObjectPrivateMethod(classTag[SomeObject.type], "someMethod", "it works") //it works
or if you have object TypeTag
def invokeObjectPrivateMethod[R](typeTag: TypeTag[_], methodName: String, args: AnyRef*): R = {
val rm = scala.reflect.runtime.currentMirror
val objectType = typeTag.tpe
val clazz = rm.runtimeClass(objectType) // see (**)
val classSymbol = rm.classSymbol(clazz)
val moduleSymbol = classSymbol.owner.info.decl(classSymbol.name.toTermName).asModule // see (*)
val moduleMirror = rm.reflectModule(moduleSymbol)
val objectInstance = moduleMirror.instance
val methodSymbol = objectType.decl(ru.TermName(methodName)).asMethod
val instanceMirror = rm.reflect(objectInstance)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(args: _*).asInstanceOf[R]
}
invokeObjectPrivateMethod(typeTag[SomeObject.type], "someMethod", "it works") //it works
or if you have object Class
def invokeObjectPrivateMethod[R](clazz: Class[_], methodName: String, args: AnyRef*): R = {
val rm = scala.reflect.runtime.currentMirror
val classSymbol = rm.classSymbol(clazz)
val moduleSymbol = classSymbol.owner.info.decl(classSymbol.name.toTermName).asModule //see (*)
val moduleMirror = rm.reflectModule(moduleSymbol)
val objectInstance = moduleMirror.instance
val objectType = classSymbol.toType
val methodSymbol = objectType.decl(ru.TermName(methodName)).asMethod
val instanceMirror = rm.reflect(objectInstance)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(args: _*).asInstanceOf[R]
}
invokeObjectPrivateMethod(SomeObject.getClass, "someMethod", "it works") //it works
or if you have object Type
def invokeObjectPrivateMethod[R](typ: Type, methodName: String, args: AnyRef*): R = {
val rm = scala.reflect.runtime.currentMirror
val classSymbol = typ.typeSymbol.asClass
val moduleSymbol = classSymbol.owner.info.decl(classSymbol.name.toTermName).asModule //see (*)
val moduleMirror = rm.reflectModule(moduleSymbol)
val objectInstance = moduleMirror.instance
val methodSymbol = typ.decl(ru.TermName(methodName)).asMethod
val instanceMirror = rm.reflect(objectInstance)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror(args: _*).asInstanceOf[R]
}
invokeObjectPrivateMethod(typeOf[SomeObject.type], "someMethod", "it works") //it works
(*) Get the module symbol, given I have the module class, scala macro
(**) How to get ClassTag form TypeTag, or both at same time?
I assume that the method didn't have overloaded versions, otherwise you should work with typ.decl(...).alternatives.find(...).get.asMethod
or typ.decl(...).alternatives.head.asMethod
.
Using Java reflection
def invokeObjectPrivateMethod[R](packageName: String, objectName: String, methodName: String, args: AnyRef*): R = {
val javaClassName = s"$packageName.${objectName.replace('.', '$')}$$"
val clazz = Class.forName(javaClassName)
val method = clazz.getDeclaredMethods.find(_.getName == methodName).get
method.setAccessible(true)
val field = clazz.getField("MODULE$")
val instance = field.get(null) // null because field is static
method.invoke(instance, args: _*).asInstanceOf[R]
}
invokeObjectPrivateMethod("com.example", "App.SomeObject", "someMethod", "it works") //it works
Using Java method handles
def invokeObjectPrivateMethod[R](packageName: String, objectName: String, methodName: String, args: AnyRef*): R = {
val javaClassName = s"$packageName.${objectName.replace('.', '$')}$$"
val clazz = Class.forName(javaClassName)
val lookup = MethodHandles.lookup
val field = clazz.getField("MODULE$")
val fieldMethodHandle = lookup.unreflectGetter(field)
val instance = fieldMethodHandle.invokeWithArguments()
val method = clazz.getDeclaredMethods.find(_.getName == methodName).get
method.setAccessible(true)
val methodHandle = lookup.unreflect(method)
methodHandle.invokeWithArguments(instance +: args : _*).asInstanceOf[R]
}
invokeObjectPrivateMethod("com.example", "App.SomeObject", "someMethod", "it works") //it works
Java NegativeTest private method with Reflection to catch custom ApplicationException
The InvocationTargetException
wraps the exception thrown within the reflectively invoked method. So you may catch the InvocationTargetException
and rethrow its cause, but I’d put that into a utility method, like
public interface TestMethod<D,A> {
void invoke(D d, A a) throws Throwable;
}
static <D,A> TestMethod<D,A> method(
Class<D> declarer, String name, Class<A> argType) throws ReflectiveOperationException {
Method method = declarer.getDeclaredMethod(name, argType);
method.setAccessible(true);
return (d,a) -> {
try {
method.invoke(d, a);
} catch(InvocationTargetException ex) {
throw ex.getTargetException();
}
};
}
which you can use like
@Test
public void testEmailPatroonFout() throws Exception{
//Verkeerde emailpatronen
List<String> emails = new ArrayList<>();
emails.add(".username@yahoo.com");
TestMethod<AccountService, String> method
= method(AccountService.class, "checkEmailPatroon", String.class);
assertThatThrownBy(() -> {
for(String email : emails){
method.invoke(AccountService, email);
}
}).isInstanceOf(ApplicationException.class)
.hasMessage(ApplicationExceptionType.ONGELDIGE_EMAIL.getMsg());
}
The shape of the TestMethod
interface allows the alternative implementation like
static <D,A> TestMethod<D,A> method(
Class<D> declarer, String name, Class<A> argType) throws ReflectiveOperationException {
Method method = declarer.getDeclaredMethod(name, argType);
method.setAccessible(true);
return MethodHandleProxies.asInterfaceInstance(
TestMethod.class, MethodHandles.lookup().unreflect(method));
}
How do I use reflection to invoke a private method with array of String as parameter
A String array is seen by the compiler as a varargs. Then your invoke method is seeing 2 String passed as parameters instead of a String array.
Java reflection to invoke private methods and fields, because the call order is different, lead to the result is different
You are accessing a variable before setting a value. Without Reflection, that would look like :
PrivateCar car = new PrivateCar();
car.drive(); //color is still null
car.color = "red";
Using the reflection won't change this order.
And without a surprise, your working example is like
PrivateCar car = new PrivateCar();
car.color = "red";
car.drive(); //color is 'red'
Related Topics
A Generic Error Occurred in Gdi+, Jpeg Image to Memorystream
Will the Ie9 Webbrowser Control Support All of Ie9'S Features, Including Svg
How to Convert Numbers Between Hexadecimal and Decimal
How to Specify a Custom Location to "Search For Views" in ASP.NET MVC
Splitting a String into Chunks of a Certain Size
Best Way to Compare Two Complex Objects
Getting All Types in a Namespace Via Reflection
Show Console in Windows Application
What Exactly Is an "Open Generic Type" in .Net
Sort a List from Another List Ids
How to Enable C# 6.0 Feature in Visual Studio 2013
Concatenate and Minify JavaScript on the Fly or at Build Time - ASP.NET MVC
Conditionally Change CSS Class in Razor View
How to Modify a CSS Style in the Code Behind File for Divs in ASP.NET
Entity Framework .Remove() Vs. .Deleteobject()