Java reflexion get private field

How to access Private Field and Method Using Reflection in Java? Example Tutorial

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

Accessing private fields in Java using reflection

In order to access a private field using reflection, you need to know the name of the field than by calling getDeclaredFields(String name) you will get a java.lang.reflect.Field instance representing that field. remember using the getDclaredFields() method and not getFields() method which returns all non-private fields both from sub class and super class.

while getDeclaredFields() returns both private and non-private fields declared in the class. Once you get the field reference you need to make it accessible by calling Field.setAccessible(true) because you are going to access the private field.

Now you can get value or private field by calling Field.get(String field_name). if you don’t call setAccessible(true) and try to access the private field using reflection you will get an Exception as shown in the below example

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 )

Читайте также:  METANIT.COM

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 the private method. Calling the private method using reflection is similar to accessing private fields reflectively. Use getDeclaredMethods(String name, Class .. parameter) to get the declared private method.

pass all the argument types needed by method or nothing if the method doesn’t accept any argument. This will give you an instance of java.lang.reflect.Method which can then be used to call the private method using reflection, as shown in the code example.

invoke private method and field in java with reflection code example

Code example of accessing private field and method using reflection

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 ())) ;

//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 ) ;
>

Читайте также:  Python sql типы данных

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

Источник

Java Reflection — Private Fields and Methods

Despite the common belief it is actually possible to access private fields and methods of other classes via Java Reflection. It is not even that difficult. This can be very handy during unit testing. This text will show you how.

Note: This only works when running the code as a standalone Java application, like you do with unit tests and regular applications. If you try to do this inside a Java Applet, you will need to fiddle around with the SecurityManager. But, since that is not something you need to do very often, it is left out of this text so far.

Note: There has been a lot of talk about disabling the ability to access private fields via reflection from Java 9. From my experiments it seems to still be possible in Java 9, but be aware that this might change in a future Java version.

Accessing Private Fields

To access a private field you will need to call the Class.getDeclaredField(String name) or Class.getDeclaredFields() method. The methods Class.getField(String name) and Class.getFields() methods only return public fields, so they won’t work. Here is a simple example of a class with a private field, and below that the code to access that field via Java Reflection:

public class PrivateObject < private String privateString = null; public PrivateObject(String privateString) < this.privateString = privateString; >>
PrivateObject privateObject = new PrivateObject("The Private Value"); Field privateStringField = PrivateObject.class. getDeclaredField("privateString"); privateStringField.setAccessible(true); String fieldValue = (String) privateStringField.get(privateObject); System.out.println("fieldValue fieldValue = The Private Value", which is the value of the private field privateString of the PrivateObject instance created at the beginning of the code sample.

Notice the use of the method PrivateObject.class.getDeclaredField("privateString"). It is this method call that returns the private field. This method only returns fields declared in that particular class, not fields declared in any superclasses.

Notice the line in bold too. By calling Field.setAcessible(true) you turn off the access checks for this particular Field instance, for reflection only. Now you can access it even if it is private, protected or package scope, even if the caller is not part of those scopes. You still can't access the field using normal code. The compiler won't allow it.

Accessing Private Methods

To access a private method you will need to call the Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods() method. The methods Class.getMethod(String name, Class[] parameterTypes) and Class.getMethods() methods only return public methods, so they won't work. Here is a simple example of a class with a private method, and below that the code to access that method via Java Reflection:

public class PrivateObject < private String privateString = null; public PrivateObject(String privateString) < this.privateString = privateString; >private String getPrivateString() < return this.privateString; >>

PrivateObject privateObject = new PrivateObject("The Private Value"); Method privateStringMethod = PrivateObject.class. getDeclaredMethod("getPrivateString", null); privateStringMethod.setAccessible(true); String returnValue = (String) privateStringMethod.invoke(privateObject, null); System.out.println("returnValue returnValue = The Private Value", which is the value returned by the method getPrivateString() when invoked on the PrivateObject instance created at the beginning of the code sample.

Notice the use of the method PrivateObject.class.getDeclaredMethod("privateString") . It is this method call that returns the private method. This method only returns methods declared in that particular class, not methods declared in any superclasses.

Notice the line in bold too. By calling Method.setAcessible(true) you turn off the access checks for this particular Method instance, for reflection only. Now you can access it even if it is private, protected or package scope, even if the caller is not part of those scopes. You still can't access the method using normal code. The compiler won't allow it.

Источник

Оцените статью