Reflection in Java class gives a good idea about how class is an entry point to all the Reflection APIs. Once you have Class object you can get information about members of the class like fields, constructors, methods. In this post we'll see how you can get method information using Java Reflection API.
Member Interface in Java Reflection API
With in the Reflection hierarchy an interface java.lang.reflect.Member
is defined which is implemented by
java.lang.reflect.Field
, java.lang.reflect.Method
, and java.lang.reflect.Constructor
classes. Thus Member is an
interface that provides identifying
information about a single member (a field or a method) or a
constructor.
This post talks about Method class and how it can be used to get information about methods using reflection. Class methods have return values, parameters, and may throw exceptions. The java.lang.reflect.Method
class provides methods for obtaining the type information for the parameters and return value. It may also be used to invoke methods on a given object.
How to get Method object
Once you have instance of the Class you can use any of the following 4 methods for getting information about methods of the class.
- getMethod(String name, Class<?>... parameterTypes)- Returns a Method object that reflects the specified
public member method of the class or interface represented by this Class object.
- getMethods()- Returns an
array containing Method objects reflecting all the public methods of the class or
interface represented by this Class object, including those declared by the class or interface and those inherited
from superclasses and superinterfaces.
- getDeclaredMethod(String name, Class<?>... parameterTypes)- Returns a Method object that reflects the
specified declared method of the class or interface represented by this Class object.
- getDeclaredMethods()- Returns an array containing Method objects reflecting all the declared methods of
the class or interface represented by this Class object, including public, protected, default (package) access, and
private methods, but excluding inherited methods.
Getting method information using Java reflection example
As a preparation for the example code let’s have a class called Parent.java
which will be extended by the class
ChildClass.java
which is the class we are going to examine. There is also an interface IntTest.java
which is
implemented by ChildClass.java.
Parent class
public class Parent {
String name;
Parent(String name){
this.name = name;
}
public void displayName(String name){
System.out.println("Hello - " + name);
}
public String getName(){
return name;
}
}
IntTest interface
public interface IntTest {
public void showValue();
}
ChildClass.java
public class ChildClass extends Parent implements IntTest{
private int value;
//Constructor
public ChildClass(String name, int value) {
super(name);
this.value = value;
}
@Override
public void showValue() {
System.out.println("Value - " + value);
}
}
Now let’s see how you can get method information using all the four methods mentioned above.
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReflectMethod {
public static void main(String[] args) {
try {
// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
// Using getMethod(methodName, parameters)
Method method = c.getMethod("displayName", String.class);
System.out.println("Method params " + Arrays.toString(method.getParameters()));
// Will throw exception
/*method = c.getDeclaredMethod("displayName", String.class);
System.out.println("Method params " + Arrays.toString(method.getParameters()));*/
Method[] methodArr = c.getMethods();
System.out.println("All methods " + Arrays.toString(methodArr));
methodArr = c.getDeclaredMethods();
System.out.println("Class methods " + Arrays.toString(methodArr));
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Output
Method params [java.lang.String arg0]
All methods [public void org.netjs.prog.ChildClass.showValue(), public java.lang.String org.netjs.prog.Parent.getName(),
public void org.netjs.prog.Parent.displayName(java.lang.String),
public final void java.lang.Object.wait() throws java.lang.InterruptedException,
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException,
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException,
public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(),
public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(),
public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
Class methods [public void org.netjs.prog.ChildClass.showValue()]
First call to the getMethod with parameters method name and parameter types returns the matching method. Then parameters
of the method are printed using the getParameters()
method of the Method class.
Second call (Which is commented) will throw NoSuchMethodException as the method displayName is inherited from the parent
class and getDeclaredMethod() will work for the methods with in the class.
getMethods()
will return all the methods of the class and also the inherited methods.
GetDeclaredMethods()
will return all the methods of the class but not the inherited one.
Getting method parameter types and return type using reflection
If we have a class called ChildClass
as follows then we can get its method parameter types and return type using
reflection.
ChildClass.java
public class ChildClass extends Parent implements IntTest{
private int value;
//Constructor
public ChildClass(String name, int value) {
super(name);
this.value = value;
}
@Override
public void showValue() {
System.out.println("Value - " + value);
}
public String getValue(String name) throws Exception{
return "Hello" + name;
}
}
// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
methodArr = c.getDeclaredMethods();
for(Method m: methodArr){
System.out.println("For Method - " + m.getName() + " Parameter types are - " + Arrays.toString(m.getParameterTypes()));
System.out.println("For Method - " + m.getName() + " Return type " + m.getReturnType());
}
Output
For Method - getValue Parameter types are - [class java.lang.String]
For Method - getValue Return type class java.lang.String
For Method - showValue Parameter types are - []
For Method - showValue Return type void
Getting method modifiers using reflection
If you want to get information about the modifiers of the methods of the class you can use getModifiers()
method
whose return type is int.
// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
methodArr = c.getDeclaredMethods();
for(Method m: methodArr){
System.out.println("For Method - " + m.getName() +
" modifier is - " + Modifier.toString(m.getModifiers()));
}
Output
For Method - getValue modifier is – public
For Method - showValue modifier is – public
Getting thrown exceptions using reflection
If you want to get information about types of exceptions declared to be thrown by the methods of the class you
can use getExceptionTypes()
method.
// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
methodArr = c.getDeclaredMethods();
for(Method m: methodArr){
System.out.println("For Method - " + m.getName() + " Thrown Exceptions - "
+ Arrays.toString(m.getExceptionTypes()));
}
Output
For Method - getValue Thrown Exceptions - [class java.lang.Exception]
For Method - showValue Thrown Exceptions - []
Invoking method using reflection
Using Java reflection API you can also invoke methods on a class at runtime. Methods are invoked using java.lang.reflect.Method.invoke()
method.
The first argument is the object instance on which this particular method is to be invoked. (If the method is static, the first argument should be null.) Subsequent arguments are the method's parameters.
// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
// Getting class object
ChildClass ch = new ChildClass("Test", 10);
Method method = c.getDeclaredMethod("getValue", String.class);
try {
String result = (String)method.invoke(ch, "Reflection");
System.out.println("Method invocation returned - " + result);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Output
Method invocation returned – HelloReflection
Invoking private method of the class using reflection
You can even invoke the private methods of the class using Reflection in Java. Using getDeclaredMethod()
you can get the private methods of the class.
Once you have the method object you can use the setAccessible() method which is inherited from class
java.lang.reflect.AccessibleObject
to set the access for the private method as true at run time and then
invoke it from another class.
Let’s say we have a ChildClass
as follows with a private method getValue()
.
public class ChildClass extends Parent implements IntTest{
private int value;
//Constructor
public ChildClass(String name, int value) {
super(name);
this.value = value;
}
@Override
public void showValue() {
System.out.println("Value - " + value);
}
private String getValue(String name) throws Exception{
return "Hello" + name;
}
}
Now you want to invoke this private method.
// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
// Getting class object
ChildClass ch = new ChildClass("Test", 10);
Method method = c.getDeclaredMethod("getValue", String.class);
method.setAccessible(true);
try {
String result = (String)method.invoke(ch, "Reflection");
System.out.println("Method invocation returned - " + result);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Output
Method invocation returned – HelloReflection
You can comment the line where access to the method is set as true.
//method.setAccessible(true);
Then if you execute it you will get the exception as follows -
java.lang.IllegalAccessException: Class org.netjs.prog.ReflectMethod can not access a member of class
org.netjs.prog.ChildClass with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.netjs.prog.ReflectMethod.main(ReflectMethod.java:32)
That's all for this topic Reflection in Java - Getting Method Information. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
-
Reflection in Java - Getting Field Information
-
Reflection in Java - Getting Constructor Information
-
Reflection in Java - Array
-
Generating Getters And Setters Using Reflection in Java
-
Core Java Basics Interview Questions And Answers
You may also like-
-
Externalizable Interface in Java
-
Java Concurrency Interview Questions And Answers
-
FlatMap in Java
-
Method Reference in Java
-
Wildcard in Java Generics
-
Race Condition in Java Multi-Threading
-
Switch Case Statement in Java With Examples
-
static Block in Java