Understanding and Analysis of Reflection Mechanism in JAVA

Keywords: Java JDBC JDK Attribute

BS53 project uses java reflection to get custom controls, then instantiates them and displays them on the page. It realizes that only one configuration file is needed to display the whole page, and supports different configurations in 5 styles. Basically all depends on reflection technology. Now let's take a brief look at reflection technology. (JDK1.6 API and sample source code are attached later.)

What is the reflex mechanism?

Sometimes, we use some knowledge, but we don't know what its technical terms are. We used a line of code when we just learned jdbc.

 Class.forNa("com.mysql.jdbc.Driver.class").newInstance();

But at that time, we only knew that line of code was generating the instance of the driver object, and we didn't know its specific meaning. You know you have to write this sentence.

Reflection mechanism:
Java reflection is a key property of Java as a dynamic (or quasi-dynamic) language.

This mechanism allows a program to obtain internal information of any well-known class at runtime through Reflection APIs, including modifiers (such as public, static, etc.), superclass (such as Object), interfaces (such as Cloneable), and all information about fields and methods, and to change the contents of fields or evoke methods at runtime.

Java reflection allows programs to load, detect, and use classes that are completely unknown during compilation at runtime. In other words, Java can load a class whose name is known at runtime and get its complete structure. Now many open frameworks use reflection mechanism, hibernate and struts are implemented by reflection mechanism. Android's current reflex operation annotations and reflex operation generics are some great examples. Lines and surfaces give us a brief look at Java reflection.

What Reflection API s are provided in JDK?

The Java reflection-related API is in the package java.lang.reflect ion. The JDK 1.6.0 reflection package is shown below:

What functions does the JAVA reflection mechanism provide?

  • Determine the class of any object at runtime

  • Constructing objects of any class at runtime

  • Membership variables and methods for judging any class at runtime
    +
    Call the method of any object at runtime
    + Create new class objects at runtime

When using Java's reflection function, it is essential to first obtain the Class object of the class, and then obtain other objects through the Class object.

Below is the test class we defined. There are private, public, protected and default methods, and we paste our code structure below (more code, download address at the end of the article):

Start our reflective journey

1/Get the Class object of the class first

Instances of Class classes represent classes and interfaces in running Java applications. There are many ways to get the Class object of a class. Go to our API and check it out.

Among them: use forName() static method in Class class; (safest / best performance)

2. Getting Fields of Classes

An attribute of a Class can be obtained by reflection mechanism, and then the attribute value corresponding to an instance of the Class can be changed. The Class class of JAVA provides several methods to get attributes of the Class.

Simple code example:

    Class<?> className = Student.class;
        System.out.println("-------------Fields  start----------------");
        // Getting attributes using getDeclared Fields is a property declared as public, including the definition in the parent class
        Field[] fields = className.getFields();
        for (Field f : fields) {
            System.out.println(f);
        }

        System.out.println("-------------Fields----------------");

        // Getting attributes using getDeclared Fields returns all defined attributes defined by the specified class, excluding those of the parent class
        fields = className.getDeclaredFields();
        for (Field f : fields) {
            System.out.println(f);
        }
        System.out.println("-------------Fields  Get finished----------------");

Print results:

-------------Fields  start----------------
public int com.ming.javareflect.Student.grade
public static final java.lang.String com.ming.javareflect.Behavior.TAG
public java.lang.String com.ming.javareflect.People.sex
public java.lang.String com.ming.javareflect.People.appearance
-------------Fields----------------
private java.lang.String com.ming.javareflect.Student.name
private java.lang.String com.ming.javareflect.Student.className
public int com.ming.javareflect.Student.grade
private java.lang.String com.ming.javareflect.Student.TAG
-------------Fields  Get finished----------------

3. Method of Getting Classes

A method of a class is obtained by reflection mechanism, and then the method corresponding to an instance of the class is invoked.

Class classes provide several methods for obtaining classes.

Simple code example:

fields = className.getDeclaredFields();
        for (Field f : fields) {
            System.out.println(f);
        }
        System.out.println("-------------Fields  Get finished----------------");
        System.out.println("-------------Methods  start----------------");
        // Getting functions using getMethods
        Method[] methods = className.getMethods();
        for (Method m : methods) {
            System.out.println(m);
        }
        System.out.println("-----------Methods--------------");
        // Getting functions using getDeclared Methods
        methods = className.getDeclaredMethods();
        for (Method m : methods) {
            System.out.println(m);
        }
        System.out.println("-------------Methods  complete----------------");

Print results:

-------------Methods  start----------------
public void com.ming.javareflect.Student.run()
public java.lang.String com.ming.javareflect.Student.getName()
public void com.ming.javareflect.Student.setName(java.lang.String)
public java.lang.String com.ming.javareflect.Student.getClassName()
public void com.ming.javareflect.Student.setClassName(java.lang.String)
public int com.ming.javareflect.Student.getGrade()
public void com.ming.javareflect.Student.setGrade(int)
public void com.ming.javareflect.Student.eat()
public void com.ming.javareflect.Student.communicate()
public boolean com.ming.javareflect.Student.love()
public void com.ming.javareflect.People.setAge(int)
public void com.ming.javareflect.People.setSex(java.lang.String)
public void com.ming.javareflect.People.setBirthday(java.util.Date)
public void com.ming.javareflect.People.setAddress(java.lang.String)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
-----------Methods--------------
public void com.ming.javareflect.Student.run()
public java.lang.String com.ming.javareflect.Student.getName()
public void com.ming.javareflect.Student.setName(java.lang.String)
public java.lang.String com.ming.javareflect.Student.getClassName()
public void com.ming.javareflect.Student.setClassName(java.lang.String)
public int com.ming.javareflect.Student.getGrade()
public void com.ming.javareflect.Student.setGrade(int)
private void com.ming.javareflect.Student.toPlayer()
protected void com.ming.javareflect.Student.justPrint(java.lang.String)
public void com.ming.javareflect.Student.eat()
public void com.ming.javareflect.Student.communicate()
public boolean com.ming.javareflect.Student.love()
-------------Methods  complete----------------

4. Constructor for Getting Classes

Get the constructor of a class through the reflection mechanism, and then call the constructor to create an instance of the class
Class classes provide several constructors for obtaining classes.

Simple code example:

System.out.println("-------------Constructor  start----------------");
        // Getting constructors using getConstructors    
        Constructor<?>[] constructors = className.getConstructors();  
        for (Constructor<?> m : constructors)  
        {  
            System.out.println(m);  
        }  

        System.out.println("-------------Constructor ----------------");

        // Getting the constructor using getDeclared Constructors     
        constructors = className.getDeclaredConstructors();  
        for (Constructor<?> m : constructors)  
        {  
            System.out.println(m);  
        }  
        System.out.println("-------------Constructor  complete----------------");

Print results:

-------------Constructor  start----------------
public com.ming.javareflect.Student()
public com.ming.javareflect.Student(java.lang.String,java.lang.String,int)
-------------Constructor ----------------
public com.ming.javareflect.Student()
public com.ming.javareflect.Student(java.lang.String,java.lang.String,int)
-------------Constructor  complete----------------

Get methods, and construct methods, no longer go into detail, just look at the keywords

5. Instances of new classes

There are several ways to create instances of new classes through reflection mechanisms

The simple example code is as follows:

    System.out.println("-------------newInstance  start----------------");
        try {
            Class clazz = Class.forName("com.ming.javareflect.People");
            /**
             * The first way to create objects
             */
            // create object
            People p = (People) clazz.newInstance();
            // set a property
            p.setName("Zhang three heroes");
            p.setAge(166);
            p.setSex("male");
            System.out.println(p.toString());

            /**
             * The second method is to create
             */
            // Acquisition construction method
            Constructor c;
            // Create objects and set properties
            c = clazz.getDeclaredConstructor(String.class, int.class,String.class);
            People p1 = (People) c.newInstance("Li Si", 699, "male");
            System.out.println(p1.toString());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("-------------newInstance  complete----------------");

The printing results are as follows:

New Instance begins - ------------------------------------------------------------------------------------------------------------------------------
People [name = Zhang Sanxia, age=166, sex = male, birthday=null, address=null, appearance=null, TAG=People]
People [name = Li Si, age=699, sex = man, birthday=null, address=null, appearance=null, TAG=People]
New Instance Completed - ----------------------------------------------------------------------------------------------------------------------------

6. Functions calling classes

The Method-like object is retrieved by reflection, and the Invoke Method of Field is called to call the function.

System.out.println("-------------Field Of Invoke  start----------------");

        try {
            Object inst;
            inst = className.newInstance();
            Method printMethod = className.getDeclaredMethod("justPrint", String.class); 
            printMethod.setAccessible(true);//If the failure is due to the lack of permission to call the private function, you need to set Accessible to true
            printMethod.invoke(inst, "hasagei"); 
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

        System.out.println("-------------Field Of Invoke  complete----------------");

Print results:

-------------Field Of Invoke  start----------------
People   Student  hasagei
-------------Field Of Invoke  complete----------------

7. Setting/Getting the Property Value of the Class

Get the Field object of the class by reflection, and call the Field method to set or get the value

Simple sample code:

System.out
                .println("-------------Reflective acquisition class Field Object, call Field Method Setting or Getting Values----------------");

        try {
            Object inst;
            inst = className.newInstance();
            Field intField = className.getField("grade");
            intField.setInt(inst, 3);
            int value = intField.getInt(inst);
            System.out.println(value + "");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out
                .println("-------------Reflective acquisition class Field Object, call Field Method Setting or Getting Values----------------");

Print results:

Reflect the Field object of the acquisition class, call the Field method to set or get the value - --------------------------------------------------------------------------------------------------------------
3
 Reflect the Field object of the acquisition class, call the Field method to set or get the value - --------------------------------------------------------------------------------------------------------------

Reflections plus configuration files make our programs more flexible:

BS53 Reflection + Configuration File Use: The configuration file used at that time was app.config file, the content was in XML format, filled in the contents of the linked database:

For example:

Write the configuration file on it, use reflection to get the configuration inside, and then load the whole desktop.

Then we can write several templates, change the content of the configuration file, or add conditions to select, which brings great convenience.

Of course, the same is true in JAVA, except that the configuration file here is. properties, which is called property file. Read the contents through reflection. So the code is fixed, but the content of the text can be changed, so that our code is much more flexible!

To sum up, JAVA reflex re-learning, flexible use of it, can make our code more flexible, but it also has its drawbacks, that is, using it will make our software performance reduced, complexity increased, so we also need to use it carefully.

Baidu cloud sample source code and JDK1.6 API download address

Posted by danoli on Sun, 21 Apr 2019 18:18:35 -0700