About Frameworks, Algorithms, and Software Engineering

Main menu

Post navigation

Accessing Private Fields and Methods – XRayInterface

This posting is about accessing private fields and methods, by adopting a foreign interface to a given java class (not already implementing the given interface). Why? Yet, in my former posting about Repairing Legacy Code I mentioned the challenge of accessing hidden state (private fields) before and after method invocations.

Having access to private fields or method could be helpful in several scenarios:

for explicitly visualizing the contents of an object

for replacing this hidden state of the object with a mock object (injecting a mocked dependency)

for checking the contents of a hidden field that is used in another algorithm

for testing methods that are complex but should not be part of the public/protected/package private API

Yet, Java Reflection would be suitable to this problem – but not very elegant in my opinion. I think of a more elegant way of having objectoriented access to hidden state. My approach works as following:

Each visible state in Java is accessible through an interface. Consider a simple Java-Bean
Name:

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

publicclassName{

privateStringfirstName;

privateStringlastName;

publicName(StringfirstName,StringlastName){

this.firstName=firstName;

this.lastName=lastName;

}

publicStringgetFirstName(){

returnfirstName;

}

publicStringgetLastName(){

returnlastName;

}

}

The inner state is not writable (after construction), but readable. So the implicit interface of this class would be:

Java

1

2

3

4

interfaceNameReadable{

StringgetFirstName();

StringgetLastName();

}

Casting
Name to
NameReadable would not work. But
Name needs not to be changed if implementing
NameReadable.

Now consider a class
Name that is only partially readable:

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

publicclassName{

privateStringfirstName;

privateStringlastName;

publicName(StringfirstName,StringlastName){

this.firstName=firstName;

this.lastName=lastName;

}

publicStringgetFirstName(){

returnfirstName;

}

}

The attribute
lastName is not readable outside of
Name. But it would be if
Name was implementing
NameReadable – or if
Name would be convertable to
NameReadable.

Though, how could this be done? The naive way would be simply to cast to NameReadable: