Package java. Lang. Reflect;
Import sun. Reflect. methodaccessor;
Import sun. Reflect. reflection;
/**
*
* Description method class
*
* Note that the reflection method is first adopted
* Class. getmethod (string name, class [] parametertypes) obtains a method object.
* String indicates the method name, And parametertypes indicates the type of each parameter in the parameter list.
* The method object in the class object is irrelevant to the actual operation object, and then this method is called through method. (Object OBJ, object [] ARGs)
* OBJ indicates the object that calls the method. ARGs indicates the value corresponding to each parameter.
*
* For example, the two methods have the same effect (of course, the performance is different)
* String Ost = "lqtest ";
* String NST = ost. substring (2, 6 );
*
* String ost2 = "lqtest ";
* Class [] types = {Int. Class, Int. Class };
* Method med = string. Class. getmethod ("substring", types );
* Object [] values = {New INTEGER (2), new INTEGER (6 )};
* String nst2 = (string) med. Invoke (ost2, values );
*
* Using Reflection, everything is changed. The class name, method name, and parameter list are all variables, rather than writing them to death.
* The specific value is not known during the runtime, rather than during the compilation period.
*
* Comment by liqiang
*
* @ Author kenth Russell
* @ Author nakul saraiya
*/
Public final
Class Method extends accessibleobject implements member {
// Class Object Defining this method
Private class clazz;
Private int slot;
// Method name, from 1.4 to intern
Private string name;
// Return type
Private class returntype;
// Parameter list
Private class [] parametertypes;
// Exception list
Private class [] exceptiontypes;
// Method Descriptor
Private int modifiers;
// Actual object of the Processing Method
Private volatile methodaccessor;
// If the current object is copied, the root points to the object before the copy.
Private method root;
// The cache of the security check of the called object. Save the last called object that passes the check. If the current called object
// Security check is performed if the previous call object is not
Private volatile class securitychecktargetclasscache;
// Constructor
Method (class declaringclass,
String name,
Class [] parametertypes,
Class returntype,
Class [] checkedexceptions,
Int modifiers,
Int slot)
{
This. clazz = declaringclass;
This. Name = Name;
This. parametertypes = parametertypes;
This. returntype = returntype;
This. exceptiontypes = checkedexceptions;
This. modifiers = modifiers;
This. Slot = slot;
}
// Generate a new object through the data of this object
Method copy (){
// Generate a new object through the data of this object
Method res = new method (clazz, name, parametertypes, returntype,
Predictiontypes, modifiers, slot );
// The root of the new object points to the original object
Res. Root = this;
// The new object shares a methodaccessor with the original object.
Res. methodaccessor = methodaccessor;
Return res;
}
// Return the class that declares this function
Public class getdeclaringclass (){
Return clazz;
}
// Return method name
Public String getname (){
Return name;
}
// Return Descriptor
Public int getmodifiers (){
Return modifiers;
}
// Obtain the return type
Public class getreturntype (){
Return returntype;
}
// Return parameter list
Public class [] getparametertypes (){
Return copy (parametertypes );
}
// Returns the exception list
Public class [] getexceptiontypes (){
Return copy (exceptiontypes );
}
// Determine whether obj is equal to the current method object
Public Boolean equals (Object OBJ ){
If (OBJ! = NULL & OBJ instanceof method) {// if it is a method object
// Transformation
Method Other = (method) OBJ;
// Define the class and method name of this method.
If (getdeclaringclass () = Other. getdeclaringclass ())
& (Getname () = Other. getname ())){
/* Avoid unnecessary cloning */
Class [] params1 = parametertypes;
Class [] params2 = Other. parametertypes;
// Compare the parameter list
If (params1.length = params2.length ){
For (INT I = 0; I <params1.length; I ++ ){
If (params1 [I]! = Params2 [I])
Return false;
}
Return true;
}
}
}
Return false;
}
// Return hashcode
Public int hashcode (){
Return getdeclaringclass (). getname (). hashcode () ^ getname (). hashcode ();
}
// String representation of the method object
Public String tostring (){
Try {
Stringbuffer sb = new stringbuffer ();
Int mod = getmodifiers ();
If (mod! = 0 ){
// Identifier
SB. append (modifier. tostring (MOD) + "");
}
// Note that the class name is displayed in the field method. The array type is different from that of class. getname ().
// Add the return type
SB. append (field. gettypename (getreturntype () + "");
// Add a class name
SB. append (field. gettypename (getdeclaringclass () + ".");
// Add method name
SB. append (getname () + "(");
// Parameter list
Class [] Params = parametertypes; // avoid clone
For (Int J = 0; j <Params. length; j ++ ){
SB. append (field. gettypename (Params [J]);
If (j <(Params. Length-1 ))
SB. append (",");
}
SB. append (")");
// Exception list
Class [] Exceptions = exceptiontypes; // avoid clone
If (exceptions. length> 0 ){
SB. append ("throws ");
For (int K = 0; k <exceptions. length; k ++ ){
SB. append (exceptions [K]. getname ());
If (k <(exceptions. Length-1 ))
SB. append (",");
}
}
Return sb. tostring ();
} Catch (exception e ){
Return "<" + E + "> ";
}
}
/**
*
* Note that the reflection method is first adopted
* Class. getmethod (string name, class [] parametertypes) obtains a method object.
* String indicates the method name, And parametertypes indicates the type of each parameter in the parameter list.
* The method object in the class object is irrelevant to the actual operation object, and then this method is called through method. (Object OBJ, object [] ARGs)
* If the called method is static, The OBJ object is null. If the method has no parameters, The args length is 0 or null.
* If the returned value is of the original type, its encapsulation class is returned. If the returned value is void, null is returned.
*/
Public object invoke (Object OBJ, object [] ARGs)
Throws illegalaccessexception, illegalargumentexception,
Invocationtargetexception
{
If (! Override ){
If (! Reflection. quickcheckmemberaccess (clazz, modifiers )){
// Obtain the Class Object of the call object
Class caller = reflection. getcallerclass (1 );
Class targetclass = (OBJ = NULL |! Modifier. isprotected (modifiers ))
? Clazz
: Obj. getclass ());
// Perform a security check if the object or method call that calls this operation is different from the cached object.
If (securitycheckcache! = Caller |
Targetclass! = Securitychecktargetclasscache ){
Reflection. ensurememberaccess (caller, clazz, OBJ, modifiers );
Securitycheckcache = caller;
// Call object that passes the security check and caches it for use in the next call
Securitychecktargetclasscache = targetclass;
}
}
}
If (methodaccessor = NULL) acquiremethodaccessor ();
Return methodaccessor. Invoke (OBJ, argS );
}
// If this object is generated by copy, the object uses the same methodaccessor as the object that generates this object.
Private void acquiremethodaccessor (){
Methodaccessor TMP = NULL;
If (root! = NULL) TMP = root. getmethodaccessor ();
If (TMP! = NULL ){
Methodaccessor = TMP;
Return;
}
// Create a methodaccessor object instead of a copy object
TMP = reflectionfactory. newmethodaccessor (this );
Setmethodaccessor (TMP );
}
// Return the methodaccessor object
Methodaccessor getmethodaccessor (){
Return methodaccessor;
}
// Set the methodaccessor object
Void setmethodaccessor (methodaccessor accessor ){
Methodaccessor = accessor;
If (root! = NULL) {// if this object is from copy
// Call its superiors recursively
Root. setmethodaccessor (accessor );
}
}
// Generate a new class array and test the content of the original array to the new array.
Static class [] Copy (class [] In ){
Int L = in. length;
If (L = 0)
Return in;
Class [] out = new class [l];
For (INT I = 0; I <L; I ++)
Out [I] = in [I];
Return out;
}
}