Created a section on using reflection with Java (#33429)

This is the beginning of a reflection section for Java. Other topics to cover should include overriding methods and calling private methods.
This commit is contained in:
Terry Lewis
2019-07-02 11:36:27 +10:00
committed by Tom
parent 29823fe495
commit bd05989c0b

View File

@ -0,0 +1,64 @@
---
title: Reflection
---
# Reflection
In Java, reflection is a powerful tool that can be used to do *virtually* anything. This can be considered a
double-edged sword, as it is at times required, yet, it is often exploited and used innappropriately.
It can, however, be particularly useful, if for whatever reason, a private method or private variable needs to be
called, a method needs to be hooked or replaced, and so on.
Reasoning for doing this may vary, for example, a developer may not have access to the original source-code for a library
that they are working with and may need to work around this constraint.
# Application
## Assigning a private or protected variable
As previously mentioned, assigning a private or protected variable can be made possible with the use of reflection.
Consider the following class:
```
public class MyClass {
private String hiddenString = "Hello!";
public String getHiddenString() {
return this.hiddenString;
}
}
```
As we can see, the `hiddenString` object is marked `private`, meaning we cannot directly access it.
It is however, accessible through the `getHiddenString()` method.
This won't allow us to change the value of the variable, we can, however, change it using reflection.
Consider the following code:
```
...
MyClass myObject = new MyClass();
...
```
We have an instance of myObject at this point, so let's mark the private variable as accessible.
```
// Create an instance of the object.
MyClass myObject = new MyClass();
// Obtain a reference to the object's private member field, we know the name of the private variable is
// 'hiddenString'.
Field hiddenStringField = myObject.getClass().getDeclaredField("hiddenString");
// Mark the field as accessible, this effectively tells the JVM that the field is not private, thus
// we can now access it.
hiddenStringField.setAccessible(true);
// The Java compiler doesn't know we have marked the field as accessible. If we wish to set the value,
// we must do so via reflection. We call the set() method on our field, supplying the target object
// (myObject) and the target value.
// We have successfully set the value, using reflection!
hiddenStringField.set(myObject, "Hello, World!");
// This will print our newly assigned string, as we have assigned the private variable within our
// myObject instance.
System.out.println(myObject.getHiddenString());
```