This is the beginning of a reflection section for Java. Other topics to cover should include overriding methods and calling private methods.
		
			
				
	
	
		
			65 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						|
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());
 | 
						|
```
 |