What is Reflection
In the runtime state, for any class, you can know all the properties and methods of the class; for any object, you can call any of its methods and properties; this dynamically obtained information and dynamic invocation of the object’s methods is called the reflection mechanism of the Java language. So what can we do with reflection?
- Analyze classes at runtime.
- Look at objects at runtime. We can also use reflection to write a toString method for all classes to use.
- Use the Method object to call any method of an object at runtime.
So this article will focus on the above three points to understand the reflection mechanism of Java. Before we start, let’s introduce a class that is essential for us to use in the process of reflection.
Class
At runtime, the Java runtime system maintains information for each object that identifies the type of the object, and the type that holds this information is the Class class. We can get the object’s Class object by using the object’s getClass()
method, like the following.
Everything in this world has a meaning, so what can we do with Class objects? We most often use Class to determine if an object belongs to a certain type, like the following.
Of course, we often use the getName()
method of the Class class to get the name of a class. Sometimes we also use its newInstance()
method to get an instance of a type (when it does not provide a common constructor).
Using reflection to analyze classes
Analyzing a class is just a matter of looking at the properties, methods and constructors of the class. The Java reflection package provides three classes Field, Method and Constructor to describe properties, methods and constructors respectively. Let’s take a look at how we can get this information about a class through the reflection mechanism.
- Obtaining properties
You can see that we can use getFields()
and getDeclaredFields()
methods to get the list of properties in the class, so what is the difference between these two methods? The difference is that the former will only return information about the common members of the class, while the latter will return information about all the members of the class including public, private, and protected, but not the members of the parent class.
- Get the constructor
- Get the methods
You can see that we can easily get the properties, constructors and methods of a class through its Class object. But what api are provided in Field, Constructor and Method respectively? Let’s take a look at them together.
getName()
method, which is used to get the corresponding name. It exists in Field, Constructor and Method classes.getModifiers()
method to get the previous modifiers (public, etc.), butgetModifiers()
returns an int value, which can be converted to a corresponding string byModifier.toString(int i)
. Also present in both Field, Constructor and Method classes.getParameterTypes()
method, used to get an array of parameter types for a method. Present in Constructor and Method classesgetReturnType()
method, used to get the return type of the method. Only exists in the Method class
With these api, we have the ability to analyze a class at runtime.
Using reflection to view objects
There are times when we may also need to reflect to get the value of the properties in the object, for example, when exporting Excel, we only know the field name of the property corresponding to the column, and then we need to reflect to get its value, and then write it to Excel. Then this section will look at how to use Java’s reflection mechanism to analyze the object together.
As in the above code, we can use the get(Object obj)
method provided in the Field
class to get the value of the property, and specific get methods are provided for the base type, such as getDouble()
. But if the above userName
is a private property, the get()
method will definitely throw an IllegalAccessException
. This is where we need to use the setAccessible()
method to override the security manager’s access control.
The setAccessible()
method is provided in the Field
, Method
, and Constructor
classes. Echoing the get()
method, Field
also provides the set()
method for setting values to properties.
Calling any method using reflection
The invoke()
method is provided in the Method class to invoke the method wrapped in the current Method object. The definition of the invoke()
method is as follows.
|
|
The first argument is the object that invokes the method, and the second argument is the method’s parameters, which are in the form of an array. Let’s see how to use reflection to invoke the sayHello()
method of the User
class.
Look at the above code we get a private method named sayHello
by getDeclaredMethod()
method (PS: if it is a public method then just use getMethod()
method), also for the private method we need to modify its access control to call it smoothly.
API collation
The above sections mentioned a lot of Api provided in the Java reflection mechanism, here are some common reflection Api that I have organized
- Class class
Api | Description |
---|---|
forName() | returns the Class object with the specified class name |
newInstance() | returns a new instance of the class |
getFields() | returns all the public properties of the class |
getDeclaredField() | returns all the properties of the class (public, private, protected) |
getMethods() | returns all the methods common to this class |
getDeclaredMethods() | returns all methods of this class (public, private, and protected) |
getConstructors() | returns all the public constructors of this class |
getDeclaredConstructors() | returns all constructors (public, private, protected) of this class |
getField() & getDeclaredField() | returns the property of this class with the specified name |
getMethod() & getDeclaredMethod() | returns the method with the specified name and parameters |
cl.getConstructor() & cl.getDeclaredConstructor() | get the constructor of the specified parameter |
- Field class
Api | Description |
---|---|
getModifiers() | returns an integer value for the modifier used to describe the property. Use the toString() method of the Modifier class to convert it to a string. |
getName() | Returns a string used to describe the name of the property. |
- Method class
Api | Description |
---|---|
getModifiers() | Returns an integer value used to describe the modifiers of the method. Use the toString() method of the Modifier class to convert it to a string. |
getName() | Returns a string used to describe the method name. |
getParameterTypes() | Returns an array of Class objects describing the types of the parameters. |
getReturnType() | Returns a Class object describing the return type. |
invoke() | invokes the method described by this object, passes the given parameters, and returns the return value of the method. |
- Constructor class
Api | Description |
---|---|
getModifiers() | returns an integer value used to describe the constructor’s modifiers. Use the toString() method of the Modifier class to convert it to a string. |
getName() | Returns a string used to describe the name of the constructor. |
getParameterTypes() | Returns an array of Class objects to describe the parameter types. |
- AccessibleObject class
Api | Description |
---|---|
setAccessible(boolean flag) | Sets the accessible flag for the reflected object. flag is true to block Java language access checking, so that the private properties of the object can also be queried and set. |
isAccessible() | Returns the value of the access flag for the reflection object. |
Conclusion
This article is about the reflection mechanism of Java and the api provided by the Field
, Method
and Constructor
classes under the reflection package.