Reflection of groovy Exploration
We know that in Java, we can obtain the dynamic nature of Java, mainly through its reflection mechanism. In groovy, there will be many ways to obtain its dynamic nature, such as mop. Therefore, in groovy, we need to call a method at runtime without using the reflection mechanism, even though we can still use the reflection mechanism in groovy; instead, use the mop mechanism or "duck type ". These mechanisms are more convenient and flexible than reflection.
Does this mean that we will no longer use the reflection mechanism in the development process of the groovy language? We said that the reflection mechanism not only allows us to call Methods dynamically during the runtime, but also has a very important feature: introspection, it is to let us know a piece of information about an object itself during the runtime, such as which class it belongs to, which attributes and methods it has, and which parent class it inherits, which interfaces are implemented, and so on. Of course, another important function is to instantiate a class during the runtime, which is also frequently used.
Therefore, in our groovy language coding process, the reflection mechanism will still play a very important role. The MOP mechanism only extends some of the weak features of the reflection mechanism.
First, we have a simple class:
PackageReflect;
ClassTestor3 {
PublicA
DefB
PrivateString C
}
We have obtained an object, as shown below:
DefT =NewTestor3 ()
Now, we want to know the class name of the object "T". In Java, we must obtain the following information:
PrintlnT. getclass (). getname ()
In groovy, gpath is widely used, and the preceding statements can be simplified as follows:
PrintlnT.Class. Name
The preceding two statements print the following results:
Reflect. testor3
If we only want to get the class name of this object and do not want to carry the package name, it will look like the following:
PrintlnT.Class. Simplename
The output is as follows:
Testor3
It is worth noting that although it is quite simple to use gpath to obtain the class, it is not always possible to obtain it. For example:
DefMap = [:]
PrintlnMap.Class
The printed result is:
Null
If you have the following statement:
PrintlnMap.Class. Simplename
Then, run it and you will get a null pointer violation.
At this time, the "getclass" method will still come in handy:
PrintlnMap. getclass ()
PrintlnMap. getclass (). simplename
PrintlnMap. getclass (). Name
The preceding statements can be correctly run and the result is:
Class java. util. linkedhashmap
Linkedhashmap
Java. util. linkedhashmap
After obtaining the class of the object, we will get its attributes. There are two methods to get the attributes of an object: obtaining "fields" and obtaining "declaredfields ". The previous method can obtain the public attributes of the object; the other method can obtain all attributes of the object. For example:
DefT =NewTestor3 ()
DefCLS = T.Class
PrintlnCls. Fields
PrintlnCls. declaredfields
The running result is:
{Public java. Lang. Object reflect. testor3.a, public static java. Lang. Long reflect. testor3. _ timestamp}
{Public Java. lang. object reflect. testor3.a, private Java. lang. object reflect. testor3. B, private Java. lang. string reflect. testor3.c, transient groovy. lang. metaclass reflect. testor3.metaclass, public static Java. lang. long reflect. testor3. _ timestamp, static Java. lang. class reflect. testor3.class $ groovy $ Lang $ metaclass, static Java. lang. class reflect. testor3.class $ org $ codehaus $ groovy $ runtime $ scriptbytecodeadapter, static Java. lang. class reflect. testor3.class $0}
Next, we want to obtain the inheritance relationship of the object, such as the parent class and interface. We can get the parent class of this object through "superclass", and get the interface implemented by it through "interfaces. For example, we have the following relationships:
PackageReflect;
InterfaceA1
{
}
InterfaceA2
{
}
ClassAImplementsA1, A2
{
}
InterfaceB1
{
}
ClassBExtendsAImplementsB1
{
}
Then, we can get the inheritance relationship between them through the following encoding:
DefM = []
A. interfaces.Each{
M <it. Name
}
PrintlnM
DefM1 = []
B. interfaces.Each{
M1 <it. Name
}
PrintlnM1
PrintlnB. superclass
The running result is:
["Reflect. A1", "reflect. A2", "groovy. Lang. policyobject"]
["Reflect. B1"]
Class reflect.
The last useful reflection function is to instantiate an object at runtime. See the following example:
Class C = Class. forname ('reflect. testor3 ')
DefT1 = C. newinstance ()
T1.a = 'hello'
PrintlnT1.a
It can be seen that the reflection mechanism is basically the same as that of Java, but because of the "duck type" function of groovy, after we instantiate an object through the "newinstance" method, it does not need to be forced type conversion like Java, but can be used directly. The above code will look like the following in Java:
Try
{
Class C = Class.Forname("Reflect. testor3 ");
Testor3 T1 = (testor3) C. newinstance ();
T1.a = "hello ";
System.Out. Println (t1.a );
}
Catch(Exception E)
{
E. printstacktrace ();
}
The running results are the same:
Hello