Java Reflection - Access Private Fields, Methods and Constructors

By Arvind Rai, November 19, 2023
On this page we will learn to access private fields, private methods and private constructors of a class using Java reflection. By default, private fields, private methods and private constructors are not accessible. We can access them using Java reflection API. Using setAccessible(true) on the instance of Field, Method and Constructor, we can access them. To create the object of a class using private constructor, reflection API provides newInstance() method. Java frameworks such as Spring and Struts use reflection API to create custom annotations.

1. Access Private Fields

Reflection API can access a private field by calling setAccessible(true) on its Field instance. Find a sample class which has private fields and private methods.
Book.java
package com.concretepage;
public class Book {
	private String bookName;
	private int length;
	private int width;
	public Book(String bookName, int length, int width) {
		this.bookName = bookName;
		this.length = length;
		this.width = width;
	}
	private int pageArea() {
		return length * width;
	}
	private String getBookName() {
		return bookName;
	}
	public void showBookDetail() {
		System.out.println(pageArea());
		System.out.println(getBookName());
	}
} 
Now find the Reflection API usage to access private fields. We will show two ways to access private fields.
1. Access all private fields of the class.
2. Access private field by using filed name.

Find the example.
PrivateFieldDemo.java
package com.concretepage;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class PrivateFieldDemo {
	//Access all private fields of the class.
	public void printAllPrivateFields(Book book) throws IllegalArgumentException, IllegalAccessException {
            Field[] fields = book.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (Modifier.isPrivate(field.getModifiers())) {
            	   field.setAccessible(true);
            	   System.out.println(field.getName()+" : "+field.get(book));
                }
            }
	}
	//Access private field by using filed name.
	public void printFieldValue(Book book, String fieldName) throws NoSuchFieldException, 
		SecurityException, IllegalArgumentException, IllegalAccessException {
		
	    Field field = book.getClass().getDeclaredField(fieldName);
            if (Modifier.isPrivate(field.getModifiers())) {
        	field.setAccessible(true);
        	System.out.println(fieldName + " : "+field.get(book));
            }
	}
	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException,
		                                               NoSuchFieldException, SecurityException {
		
		Book book = new Book("Core Java", 12, 5);
		PrivateFieldDemo ob = new PrivateFieldDemo();
		//print all private fields and their value
		ob.printAllPrivateFields(book);
		System.out.println("-----------------------");
		//print private field value by field name
		ob.printFieldValue(book, "bookName");
	}
} 

Class.getDeclaredFields(): It returns an array of Field of a class that can be public, protected, private fields but it excludes inherited fields.
Field: It provides information about a class field.
Modifier: It decodes class and member access modifiers using its static methods.
Modifier.isPrivate(): It checks if the filed, method or constructor are private using its modifiers.
field.setAccessible: When we pass true, it allows to access private field.

While working with Reflection API, we need to throw or catch some exceptions. These are IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException.

Now find the output.
bookName : Core Java
length : 12
width : 5
-----------------------
bookName : Core Java 

2. Access Private Methods

Reflection API can access a private method by calling setAccessible(true) on its Method instance.
My example includes following points.
1. Access all private methods of the class.
2. Access private method by using method name.
PrivateMethodDemo.java
package com.concretepage;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class PrivateMethodDemo {
	//Access all private methods of the class.
	public void printAllPrivateMethods(Book book) throws IllegalAccessException, 
				IllegalArgumentException, InvocationTargetException {
		
             Method[] methods = book.getClass().getDeclaredMethods();
             for (Method method : methods) {
                if (Modifier.isPrivate(method.getModifiers())) {
            	   method.setAccessible(true);
            	   Object[] args = null;
            	   Object ob = method.invoke(book, args);
            	   System.out.println(method.getName()+" : "+ ob);
                }
             }
	}
	//Access private method by using method name.
	public void printMethodValue(Book book, String methodName) throws NoSuchMethodException, SecurityException,
				       IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
	    Method method = book.getClass().getDeclaredMethod(methodName);
            if (Modifier.isPrivate(method.getModifiers())) {
        	method.setAccessible(true);
        	Object[] args = null;
        	Object ob = method.invoke(book, args);
        	System.out.println(methodName + " : "+ ob);
            }
	}
	public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException,
		       InvocationTargetException, NoSuchFieldException, SecurityException, NoSuchMethodException {
		
		Book book = new Book("Spring Security", 15, 6);
		PrivateMethodDemo ob = new PrivateMethodDemo();
		//print all private methods and their return value
		ob.printAllPrivateMethods(book);
		System.out.println("-----------------------");
		//print private method return value by method name
		ob.printMethodValue(book, "getBookName");
	}
} 

Class.getDeclaredMethods(): It returns an array of Method of a class that can be public, protected, private methods but it excludes inherited methods.
Method: It provides information about a class method.
method.setAccessible(): When we pass true, it allows to access private method.
method.invoke(): Invokes the calling method. We need to pass class instance and required arguments.

Find the output.
getBookName : Spring Security
pageArea : 90
-----------------------
getBookName : Spring Security 

3. Access Private Constructor

Reflection API can make accessible its private constructor by calling setAccessible(true) on its Constructor instance, and using newInstance(), we can instantiate the class. Find the sample class which has two private constructors, one accepts no arguments and second accepts two arguments.
Car.java
package com.concretepage;
public class Car {
	private Integer carId;
	private String carName;
	private Car(){}
	private Car(Integer carId, String carName) {
		this.carId = carId;
		this.carName = carName;
	}
	public Integer getCarId() {
		return carId;
	}
	public String getCarName() {
		return carName;
	}
} 

My example includes following points.
1. Access the private constructor for given number of arguments and types and instantiate the class.
2. Access the private constructor using given constructor name and instantiate the class.

Find the example.
PrivateConstructorDemo.java
package com.concretepage;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

public class PrivateConstructorDemo {
	//Find the private constructor for given number of arguments and types and instantiate the class. 
	public void craeteObject(int id, String name) throws InstantiationException, 
						IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
           Constructor<?>[] constructors = Car.class.getDeclaredConstructors();
           for (Constructor<?> constructor : constructors) {
             if (Modifier.isPrivate(constructor.getModifiers())) {
            	constructor.setAccessible(true);
            	Class<?>[] clazzs = constructor.getParameterTypes();
            	if (constructor.getParameterCount() == 2 && clazzs[0] == Integer.class && 
            			                             clazzs[1]  == String.class) {
	            	Object ob = constructor.newInstance(id, name);
	            	if (ob instanceof Car) {
	            		Car car = (Car)ob;
	            		System.out.println("Car Id:"+ car.getCarId());
	            		System.out.println("Car Name:"+ car.getCarName());
	            	}
            	}
             }
           }
	}
        //Find the private constructor using given constructor name and instantiate the class.
	public void craeteObjectByConstructorName(int id, String name) throws NoSuchMethodException, SecurityException,
			InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{

		Constructor<Car> constructor = Car.class.getDeclaredConstructor(Integer.class, String.class);
		if (Modifier.isPrivate(constructor.getModifiers())) {
			constructor.setAccessible(true);
			Car car = (Car)constructor.newInstance(id, name);
			System.out.println("Car Id:"+ car.getCarId());
			System.out.println("Car Name:"+ car.getCarName());
		}
	}	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		
		PrivateConstructorDemo ob = new PrivateConstructorDemo();
		ob.craeteObject(10, "Alto");
		System.out.println("-------------------------");
		ob.craeteObjectByConstructorName(20,"Santro");
	}
} 

Class.getDeclaredConstructors(): It returns an array of Constructor of a class that can be public, protected or private constructor.
Constructor: It gives the information of a class constructor.
constructor.setAccessible(): When it is set true, it allows to access private constructor.
constructor.newInstance(): The class is instantiated by using the calling constructor. We need to pass required parameters.

Find the output.
Car Id:10
Car Name:Alto
-------------------------
Car Id:20
Car Name:Santro 

4. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us