Reflection in Java is very powerful feature and allows you to access private method and fields which is not possible by any other means in Java and because of this feature of reflection many code coverage tool, static analysis tool and Java IDE like Eclipse and Netbeans has been so helpful. In last article we have seen details about private keyword in Java and learned why we should always make fields and method private in Java. There we have mentioned that private fields and methods are only accessible in the class they are declared but with reflection you can call private method and access private fields outside the class. In this article we will see simple example of accessing private field using reflection and invoking private method using reflection in Java.
Accessing private fields in Java using reflection

java.lang.IllegalAccessException: Class test.ReflectionTest can not access a member of class test.Person with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
at java.lang.reflect.Field.get(Field.java:358)
at test.ReflectionTest.main(ReflectionTest.java:31)
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
at java.lang.reflect.Field.get(Field.java:358)
at test.ReflectionTest.main(ReflectionTest.java:31)
Calling private methods in Java using reflection
In our last Java tutorial on Reflection we have seen how to call a method by its String name and we will use that information here for invoking private method. Calling private method using reflection is similar to accessing private fields reflectively. Use getDeclaredMethods(String name, Class.. parameter) to get declared private method. pass all the argument type needed by method or nothing if method doesn't accept any argument. This will give you instance of java.lang.reflect.Method which can than be used to call private method using reflection, as shown in code example.
Code example of accessing private field and method using reflection
package test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ReflectionTest {
public static void main(String args[]) throws ClassNotFoundException {
Class<Person> person = (Class<Person>) Class.forName("test.Person");
//getFields() does not return private field
System.out.println("Fields : " + Arrays.toString(person.getFields()));
//getDeclaredFields() return both private and non private fields using reflection
System.out.println("Declared Fields : " + Arrays.toString(person.getDeclaredFields()));
//getDeclaredMethods() return both private and non private methods using reflection
System.out.println("Declared methods : " + Arrays.toString(person.getDeclaredMethods()));
try {
//accessing value of private field using reflection in Java
Person privateRyan = new Person("John" , "8989736353");
Field privateField = person.getDeclaredField("phone");
//this call allows private fields to be accessed via reflection
privateField.setAccessible(true);
//getting value of private field using reflection
String value = (String) privateField.get(privateRyan);
//print value of private field using reflection
System.out.println("private field: " + privateField + " value: " + value);
//accessing private method using reflection
Method privateMethod = person.getDeclaredMethod("call");
//making private method accessible using reflection
privateMethod.setAccessible(true);
//calling private method using reflection in java
privateMethod.invoke(privateRyan);
} catch (InvocationTargetException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchFieldException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
class Person{
public String name;
private String phone;
public Person(String name, String phone){
this.name = name;
this.phone = phone;
}
private void call(){
System.out.println("Calling " + this.name +" at " + this.phone);
}
public String getName(){
return name;
}
}
Output:
Fields : [public java.lang.String test.Person.name]
Declared Fields : [public java.lang.String test.Person.name, private java.lang.String test.Person.phone]
Declared methods : [public java.lang.String test.Person.getName(), private void test.Person.call()]
private field: private java.lang.String test.Person.phone value: 8989736353
Calling John at 8989736353
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ReflectionTest {
public static void main(String args[]) throws ClassNotFoundException {
Class<Person> person = (Class<Person>) Class.forName("test.Person");
//getFields() does not return private field
System.out.println("Fields : " + Arrays.toString(person.getFields()));
//getDeclaredFields() return both private and non private fields using reflection
System.out.println("Declared Fields : " + Arrays.toString(person.getDeclaredFields()));
//getDeclaredMethods() return both private and non private methods using reflection
System.out.println("Declared methods : " + Arrays.toString(person.getDeclaredMethods()));
try {
//accessing value of private field using reflection in Java
Person privateRyan = new Person("John" , "8989736353");
Field privateField = person.getDeclaredField("phone");
//this call allows private fields to be accessed via reflection
privateField.setAccessible(true);
//getting value of private field using reflection
String value = (String) privateField.get(privateRyan);
//print value of private field using reflection
System.out.println("private field: " + privateField + " value: " + value);
//accessing private method using reflection
Method privateMethod = person.getDeclaredMethod("call");
//making private method accessible using reflection
privateMethod.setAccessible(true);
//calling private method using reflection in java
privateMethod.invoke(privateRyan);
} catch (InvocationTargetException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchFieldException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(ReflectionTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
class Person{
public String name;
private String phone;
public Person(String name, String phone){
this.name = name;
this.phone = phone;
}
private void call(){
System.out.println("Calling " + this.name +" at " + this.phone);
}
public String getName(){
return name;
}
}
Output:
Fields : [public java.lang.String test.Person.name]
Declared Fields : [public java.lang.String test.Person.name, private java.lang.String test.Person.phone]
Declared methods : [public java.lang.String test.Person.getName(), private void test.Person.call()]
private field: private java.lang.String test.Person.phone value: 8989736353
Calling John at 8989736353
Further Learning
Complete Java Masterclass
Java Fundamentals: The Java Language
Java In-Depth: Become a Complete Java Engineer!
Few old Java article which you may like to read
5 comments :
I think Reflection breaks the purpose of using private variable. So, is Reflection a bad thing ? Is there any way we can avoid this ?
I think you should provide a paragraph explaining why you should never use Reflection to access private fields/methods if you plan to write maintainable code. Reflection's primary purpose is not to be used in everyday common development tasks. Your article, as is, might result in a poor decision by a junior developer without giving him/her the chance to take a step back and wonder why the need to such a maneuver in the first place. Other than that, very nicely written piece of tutorial. :)
I think there is a slight typo, we pass the object to Field.get instead of Field.get(String field_name)
Very good article!
With this possibility we can always follow the rule of making private the "fields" of a class, and after we could use a dynamic system to use the fields name (.getName())and the fields type (.getType()) without the need of knowing the name of the fields of a given class.
Good article.
Kindly give an example to call private methods with arguments and non-void return types.
Post a Comment