Detailed use of Java reflection Reflect

A. What is reflected

Typically contains a class attribute, method, constructor functions, etc., under normal circumstances conventional Java class objects Further, various properties and methods by calling the object, and is reflected by the existing Java object, which in turn give information about their class, related method belongs to the class of calls.

Two reflection basis Class

2.1 Class Class Overview

We know that in the Java world, all things are objects. In fact, the class instance object is itself an object, any one of the classes are Class class.

// definition of a class SuperHero 
public class SuperHero {}

SuperHero class as defined above, is also an object class,

Object: SuperHero instance of class Class is the class, Class class is a class type SuperHero, and therefore the object;

Class: in a class way to create, SuperHero itself can call SuperHero ironMan = new SuperHero () is instantiated, the entity ironMan is created, and therefore also the class.

Class class is very special, it represents a class of class type, are not inherited, only a Class object for each class, Class class has no public constructor. In contrast, Class objects built by the Java virtual machine to automatically because the loaded class, and by defineClass method calls the class loader in the original Java types (boolean, byte, char, short, int, long, float, and Double), and key word void is also represented as Class objects

// Class source, final modification is not inherited, the constructor is private, not manually instantiate the 
public class Class Final <T> { 
    private Class (ClassLoader Loader) { 
        // for the Initialize Final Field classLoader. Initialization of The value of NON- null 
        // Prevents Future Assuming the JIT optimizations from the this Final Field IS null. 
        classLoader = Loader; 
    } 
}
public static void main(String[] args) {
    try {
        Class clazz1 = Class.forName("java.lang.Integer");
        Class clazz2 = Class.forName("java.lang.Integer");
        System.out.println(clazz1 == clazz2);
        System.out.println(int.class);
        System.out.println(void.class);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

Operating results as follows:

true
int
void

2.2 Class class object acquired in three ways

Define a class

package reflectdemo;
import java.io.Serializable;

/**
 * 超级英雄类
 */
public class SuperHero implements Serializable {
    
    public static final String ADDRESS = "earth";
    
    private String id;

    private String name;

    private Integer age;

    private String skill;

    public SuperHero() {
    }

    public SuperHero(String id, String name, Integer age, String skill) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.skill = skill;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
    
    public void print(){
        System.out.println("超级英雄:" + this.name);
    }
}

2.2.1 Class get through the object

public static void main(String[] args) {
    SuperHero ironMan = new SuperHero("1","钢铁侠",35, "战甲");
    Class clazz = ironMan.getClass();
    System.out.println(clazz.getName());
}

Output:

reflectdemo.SuperHero

2.2.2 Class by class acquired

public static void main(String[] args) {
    Class clazz = SuperHero.getClass();
    System.out.println(clazz.getName());
}

Output:

reflectdemo.SuperHero

2.2.3 incoming class path to obtain Class

public static void main(String[] args) {
    try {
        Class clazz = Class.forName("reflectdemo.SuperHero");
        System.out.println(clazz.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

Output:

reflectdemo.SuperHero

Three ways to create ways:

The first approach has been the object, all of the operations can be performed directly by the object,

The second approach requires the introduction of import the class, nor is it the usual way,

A third class of the incoming path only can get information classes, the most common way.

2.2.4 class information acquisition method used

static void main public (String [] args) { 
    the try { 
        Class = clazz the Class.forName ( "reflectdemo.SuperHero"); 
        // get a class name (including the path) 
        System.out.println (clazz.getName ()); 
        / / Get the class name (without path) 
        System.out.println (clazz.getSimpleName ()); 
        // Get own package 
        System.out.println (clazz.getPackage ()); 

        // create objects by class 
        SuperHero Hero = ( SuperHero) clazz.newInstance (); 
        
    } the catch (a ClassNotFoundException E) { 
        e.printStackTrace (); 
    } 
}

Output:

reflectdemo.SuperHero
SuperHero
package reflectdemo

Click here to explain in advance: Class two identical function method, wherein if a word with a Declared, represents for all the variables declared in the class, method, configuration functions, etc., without a corresponding method Declared words, it indicates only public (public) member variables, the method works, the following description will not be repeated, with the following method Declared only words to explain.

Three reflective - Constructor

3.1 getDeclaredConstructor(Class<?>...parameterTypes)

{class ClassUtils public 
    / ** 
     * Get constructor 
     * @param clazz class 
     * @param params parameter type constructor 
     * @throws a NoSuchMethodException 
     * / 
    public static void getDeclaredConstructor (Class clazz, Class [] the params) {throws a NoSuchMethodException 
        the System.out. the println (clazz.getDeclaredConstructor (the params)); 
    } 
} 

public class ClassTest { 
    public static void main (String [] args) { 
        the try { 
            class = clazz the Class.forName ( "reflectdemo.SuperHero"); 
            // print a constructor parameter 
            ClassUtils.getDeclaredConstructor (clazz, null); 
            // constructor printed reference
            ClassUtils.getDeclaredConstructor(clazz, new Class[]{String.class, String.class, Integer.class, String.class});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The output is:

public reflectdemo.SuperHero()
public reflectdemo.SuperHero(java.lang.String,java.lang.String,java.lang.Integer,java.lang.String)

3.2 getDeclaredConstructors()

{class ClassUtils public 
    / ** 
     * traversal constructor 
     * @param clazz class 
     * / 
    public static void getDeclaredConstructors (Class clazz) { 
        // Get all constructors 
        the Constructor [] = clazz.getDeclaredConstructors Constructors (); 
        for (the Constructor constructor: constructors) { 
            // constructors direct printing 
            System.out.println (constructor); 

            // constructors name Print 
            System.out.println (constructor.getName ()); 
            // print constructor parameters 
            parameter [] parameters = constructor. the getParameters (); 
            for (the Parameter Parameter: Parameters) { 
                of System.out.print (Parameter); 
                of System.out.print ( ","); 
            }
            System.out.println("---------------------");
        }
    }
}

public class ClassTest {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("reflectdemo.SuperHero");
            //遍历构造函数
            ClassUtils.getDeclaredConstructors(clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The output is:

public reflectdemo.SuperHero()
reflectdemo.SuperHero
---------------------
public reflectdemo.SuperHero(java.lang.String,java.lang.String,java.lang.Integer,java.lang.String)
reflectdemo.SuperHero
java.lang.String arg0, java.lang.String arg1, java.lang.Integer arg2, java.lang.String arg3, ---------------------

Four reflection - a member variable

4.1 getDeclaredField(String name)

{class ClassUtils public 
    / ** 
     * Get Attribute Fields 
     * @param clazz class 
     * @param fieldName property name 
     * @throws Exception 
     * / 
    public static void getDeclaredField (Class clazz, String the fieldName) throws Exception { 
        System.out.println (clazz. getDeclaredField (the fieldName)); 
    } 
} 
public class ClassTest { 
    public static void main (String [] args) { 
        the try { 
            class = clazz the Class.forName ( "reflectdemo.SuperHero"); 
            // properties public test 
            ClassUtils.getDeclaredField (clazz, "ADDRESS"); 
            // test private property  
            ClassUtils.getDeclaredField (clazz, "name") ;
        } catch (Exception e) {
            e.printStackTrace (); 
        } 
    } 
}

The output is:

public static final java.lang.String reflectdemo.SuperHero.ADDRESS
private java.lang.String reflectdemo.SuperHero.name

4.3 getDeclaredFields()

{class ClassUtils public 
    / ** 
     * has traversed the object member variables clazz 
     * @param clazz 
     * / 
    public static void getDeclaredFields (Class clazz) { 
        Field, [] = clazz.getDeclaredFields Fields (); 
        for (Field, Field: Fields) { 
            // to set values you need to add the following phrase, reflecting object without using the Java language access checks when using 
            //field.setAccessible(true); 
            
            // direct printing Field, 
            System.out.println (Field); 
            // manual Get the name of the variable type and the variable 
            System.out.println (Field.getType () getName () + "." + field.getName ()); 
            System.out.println ( "----------- --------- "); 
        } 
    } 
}  
public class ClassTest {
    public static void main (String [] args) {
        {the try 
            Class = clazz the Class.forName ( "reflectdemo.SuperHero"); 
            // traversing member variable 
            ClassUtils.getDeclaredFields (clazz); 
        } the catch (Exception E) { 
            e.printStackTrace (); 
        } 
    } 
}

The output is:

public static final java.lang.String reflectdemo.SuperHero.ADDRESS
java.lang.String ADDRESS
--------------------
private java.lang.String reflectdemo.SuperHero.id
java.lang.String id
--------------------
private java.lang.String reflectdemo.SuperHero.name
java.lang.String name
--------------------
private java.lang.Integer reflectdemo.SuperHero.age
java.lang.Integer age
--------------------
private java.lang.String reflectdemo.SuperHero.skill
java.lang.String skill
--------------------

V. reflection - member method

5.1 getDeclaredMethod(String name, Class<?>... parameterTypes)

{class ClassUtils public 
    / ** 
     * The method of obtaining a member of 
     * @param clazz class 
     * @param methodName method name 
     * @param params parameter list 
     * @throws Exception 
     * / 
    public static void getDeclaredMethod (Class clazz, String methodName, Class [] the params) Exception {throws 
        Method, Method = clazz.getDeclaredMethod (methodName, the params); 
        System.out.println ( "direct printing"); 
        System.out.println (Method); 

        System.out.println ( "Construction manual"); 
        // Get returns the type 
        of System.out.print (Method.getReturnType () getSimpleName () + "."); 
        // Get the name of the method 
        System.out.print (method.getName () + "( "); ");
        // Get parameter type
        Class[] paramTypes = method.getParameterTypes();
        for(int i = 0; i < paramTypes.length; i++){
            Class param = paramTypes[i];
            if(i < paramTypes.length - 1){
                System.out.print(param.getSimpleName() + ", ");
            }else {
                System.out.print(param.getSimpleName());
            }
        }
        System.out.print(")");
        System.out.println();
    }
}
public class ClassTest {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("reflectdemo.SuperHero");
            //打印无参数方法
            ClassUtils.getDeclaredMethod(clazz, "getName", null);
            //打印有参数方法
            ClassUtils.getDeclaredMethod(clazz, "setName", new Class[]{String.class});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The output is:

Direct printing 
public java.lang.String reflectdemo.SuperHero.getName () 
to build manually 
String getName () 
directly print 
public void reflectdemo.SuperHero.setName (java.lang.String) 
to build manually 
void setName (String)

5.2 getDeclaredMethods()

{class ClassUtils public 
    / ** 
     * traversal method 
     * @param clazz 
     * / 
    public static void getDeclaredMethods (Class clazz) { 
        // get the class of all methods declared 
        Method, [] = clazz.getDeclaredMethods Methods (); 
        for (Method, Method: methods) { 
            System.out.println (method); 
        } 
    } 
} 
public class ClassTest { 
    public static void main (String [] args) { 
        the try { 
            class = clazz the Class.forName ( "reflectdemo.SuperHero"); 
            // traversal methods 
            ClassUtils.getDeclaredMethods (clazz); 
        } the catch (Exception E) { 
            e.printStackTrace (); 
        } 
    }
}

The output is:

public java.lang.String reflectdemo.SuperHero.getName()
public java.lang.String reflectdemo.SuperHero.getId()
public void reflectdemo.SuperHero.setName(java.lang.String)
public void reflectdemo.SuperHero.print()
public java.lang.String reflectdemo.SuperHero.getSkill()
public void reflectdemo.SuperHero.setAge(java.lang.Integer)
public void reflectdemo.SuperHero.setSkill(java.lang.String)
public void reflectdemo.SuperHero.setId(java.lang.String)
public java.lang.Integer reflectdemo.SuperHero.getAge()

5.3 execution method

{class ClassUtils public 
    / ** 
     * set method was executed (by Method invoke method) 
     * @param entities O to be performed 
     * @param methodName method name 
     * @param params Method Parameter Type 
     * @throws Exception 
     * / 
    public static void invokeSetMethod ( O Object, String methodName, Class [] the params) throws Exception { 
        method, method o.getClass = () getDeclaredMethod (methodName, the params);. 
        Method.invoke (O, "Iron Man"); 
    } 

    / * 
     * get method performed (method by the invoke method) 
     entity to be executed * @param o 
     * @param methodName method name 
     * @throws Exception 
     * /  
    public static void invokeGetMethod (O Object, String methodName) throws Exception {
        method method o.getClass = () getDeclaredMethod (methodName).;
        Object obj = method.invoke(o);
        System.out.println(obj);
    }
}
public class ClassTest {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("reflectdemo.SuperHero");
            //创建实体
            Object o = clazz.newInstance();
            //调用set方法
            ClassUtils.invokeSetMethod(o, "setName", new Class[]{String.class});
            //调用get方法
            ClassUtils.invokeGetMethod(o, "getName");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The output is:

iron Man

The following is a description of the API invoke a method

public Object invoke(Object obj, Object... args) throws IllegalAccessException,
       IllegalArgumentException, InvocationTargetException

Called by the base object on the method of the object with the specified parameters indicated.

If the underlying method is static, then the specified obj parameter is ignored. It may be null.

If the required number of formal parameters of the underlying method is 0, the length of the array is provided args is 0 or null.

If the underlying method is an instance method, it uses a dynamic method lookup call, such as "the Java Language Specification," second edition, section 15.12.4.4; particular run will occur when the target object based on the type of coverage.

If the underlying method is static, then if the method has not been initialized, then the class of the method statement will be initialized.

If the method completes normally, the return value will be returned to the caller; if the value has a primitive type, it is first suitably packaged in the subject. However, if the value of the type having an array of basic type, the element of the array is not contained in the object; in other words, a return to the original type of array. If the underlying method return type is void, the call returns null.

  • parameter

    obj - the object from the underlying method is called

    args - parameters for the method call

  • result

    The method represented by this object calls args on the obj

  • abnormal

    IllegalAccessException - If this method object is to enforce Java language access control and the underlying method is inaccessible.

    IllegalArgumentException - if the method is an instance method, and examples of the specified object is not declared parameters underlying method (or a subclass or implementor) of the class or interface; and if the actual number of different formal parameter; unwrapping conversion parameter if the original failure; or if possible after deployment, by invoking a method, the parameter values ​​can not be converted to the corresponding formal parameter.

    InvocationTargetException - if the underlying method throws an exception.

    NullPointerException - if the object is empty, the method is an instance method.

    ExceptionInInitializerError - If this method triggered initialization failed.

VI. Summary

As defined herein for reflection, reflective important during use, commonly used classes and methods are explained, including Class class, the Constructor class, Field, class, and using the Method described class. Reflection mechanism allows a determination target object belongs to any class, any configuration of a class at run time, a determination of any class has member variables and methods, a call arbitrary object. Greatly improving the flexibility and scalability of the system, but everything has two sides, reflecting the destruction of the properties of Java package, relatively unsafe, we need to consider, as appropriate, depending on the scene, if imperfect, please criticism and hope to make progress together ,Thank you!

Guess you like

Origin www.linuxidc.com/Linux/2019-08/160185.htm