Summary of Java reflection mechanism

  • 2020-04-01 02:15:23
  • OfStack

What is the reflex mechanism
In simple terms, the reflection mechanism refers to the ability of a program to obtain information about itself while it is running. In Java, given the name of the class, all information about the class is available through reflection.

Where is reflection used
In some cases, we used some knowledge, but don't know what is the term of it, just used one line of code, when you learn the JDBC Class. The class.forname (". Com. Mysql. JDBC Driver. The Class "). The newInstance (); But at the time, we only knew that the line of code was generating the driver object instance, not what it meant. After listening to the reflection mechanism this lesson, just know, originally this is reflection, now many open frameworks are used reflection mechanism, hibernate, struts are implemented with reflection mechanism.

The advantages and disadvantages of reflection mechanism
Why use reflection? Why don't you just create objects, and that's where the dynamic versus the static concept comes in,
Static compilation: Determines the type at compile time, binds the object, that is, passes.

Dynamic compilation: The runtime determines the type and binds the object. Dynamic compilation maximizes the flexibility of Java and embodies the application of polymorphism to reduce coupling between classes.

In a word, the advantage of reflection is that it can dynamically create objects and compile, which shows great flexibility, especially in J2EE development. For example, a large software, it is impossible to design it perfectly, when the program compiled, released, when we found that some features need to be updated, we can not ask users to uninstall the previous, and then reinstall the new version, if so, the software is certainly not many people. With static, you need to recompile the entire program to achieve the function of the update, and with reflection, it can not uninstall, only need to run the dynamic creation and compilation, you can achieve the function.

The downside is that it has an impact on performance. Using reflection is basically an interpretive operation where we can tell the JVM what we want to do and it satisfies our requirements. This type of operation is always slower than simply performing the same operation directly.

What information can be obtained by using the reflection mechanism
In a word, it gets whatever information is in the Class, but only if it knows the name of the Class, or if there is no text to follow.

Class c = Class. Class.forname (" className "); Note: the className must be the full name, that is, it must contain the package name, for example, cn.net java.pojo.userinfo;
The Object obj = c.n ewInstance (); // create an instance of the object
OK, now that you have an object, everything is easy. You can have whatever information you want.    
Method to get the constructor
Constructor getConstructor(Class[] params)// gets the public Constructor as specified

Constructor[] getConstructors()// gets all constructors for public

Constructor getDeclaredConstructor(Class[] params)// gets public and non-public constructors based on the specified arguments

Constructor[] getDeclaredConstructors()// gets all of public's constructors

Method to get a class method
Method getMethod(String name, Class[] params), gets the Method by Method name, parameter type

Method[] getMethods()// get all public methods

Method getDeclaredMethod(String name, Class[] params)// get public and non-public methods by Method name and parameter type

Method[] getDeclaredMethods()// get all public and non-public methods

Methods to get properties in a class
Field getField(String name)// get the corresponding public variable according to the variable name

Field[] getFields()// gets all the public methods in the class

Field getDeclaredField(String name)// get public and non-public variables by method name

Field[] getDeclaredFields()// gets all the public and non-public methods in the class
These are the only things that are commonly used. Knowing these, the rest is easy...

What can you do with the reflex mechanism
Beginning in the use of JDBC, writes vomiting when writing the access database, there are eight table, each table has to add and delete operation, at that time still don't know how the concept of reflection mechanism, so the different tables to create different dao class, this not only velocity, and the code redundancy, looking at the same, is the most terrible of then copy directly modify, due to various low-level mistakes easily (case, one more or less a letter......) One mistake will get you nowhere.

With Java reflection mechanism, everything is easy to do, just need to write a dao class, four methods, add, delete, change check, pass in different objects, OK, there is no need to create a dao class for every table, reflection mechanism will automatically help us to do the rest of the things, this is the benefit of it. Basically, the reflection mechanism is designed to do the repetitive and regular things for us, so a lot of today's automatic code generation software USES the reflection mechanism to do, as long as you follow the rules to enter the relevant parameters, so the low-level programmer is slowly killed, why? Because the code all need not write, random person can develop, still need programmer what? So there's only one way out, and that's to work harder and harder and harder, to be a senior programmer, to make software that's dumb, to let other programmers know. Cool off to the side, hehe ~

Six, use reflection mechanism to realize the database data, check the example
Basic principles; When saving data, take out all the property values of the objects that need to be saved and then piece together the SQL statement query, all the data to the query into a Java object.

Rules of the game: as the saying goes, no rules do not square, especially for the program, it can only do things with rules, no rules it can not do, good, then first set rules
1) Each table object in the database is a pojo class, and each field in the table corresponds to an attribute in the pojo class. Also, the pojo class name is the same as the table name, the property name is the same as the field name, and case does not matter, because databases are generally case-insensitive  

2) Add standard set and get methods for each property in the pojo class.
With the rules of the game, let's play.

1. First of all, there is a table in the database. Suppose the database name is: blogsystem. As shown in figure:

< img border = 0 SRC = "/ / img.jbzj.com/file_images/article/201309/201309110936572.png" >
2. Create corresponding pojo classes:


package cn.netjava.pojo; 

public class UserInfo { 
private int id; 
private String name; 
private String pwd; 
private int age; 

@Override
public String toString() { 
    return "UserInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", age="
            + age + "]"; 
} 
public int getId() { 
    return id; 
} 
public void setId(int id) { 
    this.id = id; 
} 
public String getName() { 
    return name; 
} 
public void setName(String name) { 
    this.name = name; 
} 
public String getPwd() { 
    return pwd; 
} 
public void setPwd(String pwd) { 
    this.pwd = pwd; 
} 
public int getAge() { 
    return age; 
} 
public void setAge(int age) { 
    this.age = age; 
} 

}

2. Write the factory class to get the database connection:

package cn.netjava.factory; 

import java.sql.Connection; 
import java.sql.DriverManager; 

public class Connect2DBFactory { 
    public static Connection getDBConnection() { 
        Connection conn = null; 
        try { 
            Class.forName("com.mysql.jdbc.Driver"); 
            String url = "jdbc:mysql://localhost:3306/blogsystem"; 
            String user = "root"; 
            String password = "netjava"; 
            conn = DriverManager.getConnection(url, user, password); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 

        return conn; 
    } 
}

3, the fun begins, write operation database dao class

package cn.netjava.session; 

import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.util.ArrayList; 
import java.util.List; 

import cn.netjava.factory.Connect2DBFactory; 
import cn.netjava.pojo.UserInfo; 

public class NetJavaSession { 
    
    public static String getSaveObjectSql(Object object) { 
        //Define an SQL string
        String sql = "insert into "; 
        //Get the class of the object
        Class c = object.getClass(); 
        //Get all the methods in the object
        Method[] methods = c.getMethods(); 
        //Gets all the properties in the object
        Field[] fields = c.getFields(); 
        //Get the name of the object class
        String cName = c.getName(); 
        //Resolve the table name from the class name
        String tableName = cName.substring(cName.lastIndexOf(".") + 1, 
                cName.length()); 
        sql += tableName + "("; 
        List<String> mList = new ArrayList<String>(); 
        List vList = new ArrayList(); 
        for (Method method : methods) { 
            String mName = method.getName(); 
            if (mName.startsWith("get") && !mName.startsWith("getClass")) { 
                String fieldName = mName.substring(3, mName.length()); 
                mList.add(fieldName); 
                System.out.println(" The field name ----->" + fieldName); 
                try { 
                    Object value = method.invoke(object, null); 
                    System.out.println(" The value returned by the execution method: " + value); 
                    if (value instanceof String) { 
                        vList.add(""" + value + """); 
                        System.out.println(" The field values ------>" + value); 
                    } else { 
                        vList.add(value); 
                    } 
                } catch (Exception e) { 
                    e.printStackTrace(); 
                } 
            } 
        } 
        for (int i = 0; i < mList.size(); i++) { 
            if (i < mList.size() - 1) { 
                sql += mList.get(i) + ","; 
            } else { 
                sql += mList.get(i) + ") values("; 
            } 
        } 
        for (int i = 0; i < vList.size(); i++) { 
            if (i < vList.size() - 1) { 
                sql += vList.get(i) + ","; 
            } else { 
                sql += vList.get(i) + ")"; 
            } 
        } 

        return sql; 
    } 

    public static List getDatasFromDB(String tableName, int Id) { 

        return null; 

    } 

    
    public int saveObject(Object object) { 
        Connection con = Connect2DBFactory.getDBConnection(); 
        String sql = getSaveObjectSql(object); 
        try { 
            // Statement statement=(Statement) con.createStatement(); 
            PreparedStatement psmt = con.prepareStatement(sql); 
            psmt.executeUpdate(); 
            return 1; 
        } catch (SQLException e) { 
            e.printStackTrace(); 
            return 0; 
        } 
    } 

    
    public Object getObject(String className, int Id) { 
        //Get the table name
        String tableName = className.substring(className.lastIndexOf(".") + 1, 
                className.length()); 
        //Create a Class object based on the Class name
        Class c = null; 
        try { 
            c = Class.forName(className); 

        } catch (ClassNotFoundException e1) { 

            e1.printStackTrace(); 
        } 
        //Piece together query SQL statements
        String sql = "select * from " + tableName + " where Id=" + Id; 
        System.out.println(" To find the sql Statement: " + sql); 
        //Get a database link
        Connection con = Connect2DBFactory.getDBConnection(); 
        //Create an instance of the class
        Object obj = null; 
        try { 

            Statement stm = con.createStatement(); 
            //Gets the result set returned by executing a lookup statement
            ResultSet set = stm.executeQuery(sql); 
            //Gets an array of methods for the object
            Method[] methods = c.getMethods(); 
            //Traversing the result set
            while (set.next()) { 
                obj = c.newInstance(); 
                //Method of traversing an object
                for (Method method : methods) { 
                    String methodName = method.getName(); 
                    //If the object's methods start with a set
                    if (methodName.startsWith("set")) { 
                        //Gets the name of the field in the data table from the method name
                        String columnName = methodName.substring(3, 
                                methodName.length()); 
                        //Gets the parameter type of the method
                        Class[] parmts = method.getParameterTypes(); 
                        if (parmts[0] == String.class) { 
                            //If the parameter is of type String, the corresponding value is obtained from the result set by column name, and the set method is changed
                            method.invoke(obj, set.getString(columnName)); 
                        } 
                        if (parmts[0] == int.class) { 
                            method.invoke(obj, set.getInt(columnName)); 
                        } 
                    } 

                } 
            } 

        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        return obj; 
    } 
}

4. How is the test effect at the beginning?

package cn.netjava.tester; 

import cn.netjava.pojo.UserInfo; 
import cn.netjava.session.NetJavaSession; 

public class Tester { 
    public static void main(String args[]) { 
        //Gets the NetJavaSession object
        NetJavaSession session = new NetJavaSession(); 
        //Create a UserInfo object
        UserInfo user = new UserInfo(); 
        //Sets the properties of the object
        user.setId(6988); 
        user.setAge(44); 
        user.setPwd("pwd"); 
        user.setName("champion"); 
        //Save the object to the database
        String sql = session.getSaveObjectSql(user); 
        System.out.println(" Save object sql Statement: " + sql); 
        //To find the object
        UserInfo userInfo = (UserInfo) session.getObject( 
                "cn.netjava.pojo.UserInfo", 6988); 
        System.out.println(" Information obtained: " + userInfo); 

    } 
}

5. Printed results:

< img border = 0 SRC = "/ / img.jbzj.com/file_images/article/201309/201309110936573.png" >

Seven, the total section
Overall, Java reflection mechanism is a very useful thing, can solve a lot of dead things with it, because of the reflection mechanism flexible line is very big, with him, we don't spend too much time to write to manipulate database code, but way more time on the project of logic functions, this may greatly reduce development time, and the readability of the code good. Many of the first open source frameworks are just reflection mechanisms that simply configure a file and then invoke its methods as a rule.


Related articles: