Home  >  Article  >  Java  >  Java reflection mechanism

Java reflection mechanism

高洛峰
高洛峰Original
2016-12-12 11:36:531183browse

1. What is the reflection mechanism? Simply put, the reflection mechanism means that the program can obtain its own information when it is running. In java, as long as the name of the class is given,
Then you can obtain all the information of the class through the reflection mechanism.
2. Where to use the reflection mechanism
Sometimes, we have used some knowledge, but we don’t know what its professional terminology is. When we just learned jdbc, we used a line of code,
Class.forName("com.mysql.jdbc .Driver.class").newInstance(); But at that time, I only knew that that line of code generated a
driver object instance, and I didn’t know its specific meaning. After listening to the lesson on reflection mechanism, I realized that this is reflection. Nowadays, many open frameworks use reflection mechanism. Hibernate and Struts are all implemented using reflection mechanism.
3. Advantages and Disadvantages of Reflection Mechanism
Why use reflection mechanism? Isn’t it enough to create objects directly? This involves the concepts of dynamic and static.
Static compilation: Determine the type at compile time and bind the object, that is, pass.
Dynamic compilation: determine the type and bind the object at runtime. Dynamic compilation maximizes the flexibility of Java, embodies polymorphic applications, and reduces the coupling between classes.
In a word, the advantage of the reflection mechanism is that it can dynamically create objects and compile, showing great flexibility, especially in the development of J2EE
Its flexibility is very obvious. For example, for a large-scale software, it is impossible to design it perfectly in one go. After the program is compiled and released, when it is found that certain functions need to be updated, we cannot ask the user to uninstall the previous one and then use it again. Reinstall the new version, if
This is the case, this software will definitely not be used by many people. If it is static, the entire program needs to be recompiled once to realize the function update. But if it uses the reflection mechanism, it does not need to be uninstalled. It only needs to be dynamically created and compiled at runtime to realize the function. .
Its disadvantage is that it affects performance. Using reflection is basically an interpreted operation, we can tell the JVM what we want to do and it
meets our requirements. Such operations are always slower than just performing the same operation directly.
4. What information can be obtained by using the reflection mechanism? The full name of the class to create a Class object.
Class c=Class.forName("className"); Note: className must be the full name, that is, it must include the package name, for example, cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();/ / Create an instance of the object
OK, once you have the object, everything is easy to do, and you can get whatever information you want.
How to get the constructor
Constructor getConstructor(Class[] params)//Get the public constructor according to the specified parameters

Constructor[] getConstructors()//Get all the public constructors

Constructor getDeclaredConstructor(Class[] params) //Get public and non-public constructors according to the specified parameters

Constructor[] getDeclaredConstructors()//Get all public constructors
Get the method of class method
Method getMethod(String name, Class[] params), according to the method Name, parameter type to get the method

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

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

Method[] getDeclaredMethods()//Get all public and non-public methods
Method to get the attributes in the class
Field getField(String name)//Get the corresponding public variable according to the variable name

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

Field getDeclaredField(String name)//Get public and non-public variables according to the method name

Field[] getDeclaredFields()//Get all the public and non-public methods in the class
These are the commonly used ones. If you know these, everything else is easy...
5. What can you do with the reflection mechanism
I just started using jdbc At that time, when I was writing to access the database, I felt like vomiting. There were eight tables, and each table had addition, deletion, modification, and search operations.
At that time, I didn’t know the concept of reflection mechanism, so I created different DAOs for different tables. Class, this not only speeds up development, but also makes the code
extremely redundant. The most terrible thing is that if you look at the same thing and then directly copy and modify it, it is easy to make all kinds of low-level mistakes (upper and lower case, one more
or one less Letters...), one mistake can take you a long time to figure out.反 With the Java reflection mechanism, everything is easy to do. You only need to write a DAO class, four methods, add deletion and change, and pass the different objects. It is OK. You do n’t need to create a DAO class for each table. The mechanism automatically does the rest for us, and that's the beauty of it. To put it bluntly, the reflection mechanism is specifically designed to help us do repetitive and regular things, so now many software that automatically generates code is done using the reflection mechanism. As long as you enter the relevant parameters according to the rules, so low-level programs Members were slowly being wiped out. Why? Because there is no need to write code, anyone can develop it, so why do you need a programmer? So we have only one way out, which is to work hard and work hard, become a senior programmer, specialize in developing fool's software, and let other programmers go aside and cool off, haha~
6. Use the reflection mechanism to add database data, check examples
Basic principle; when saving data, take out all the attribute values ​​​​of the objects that need to be saved and then piece together the sql statement. When querying, package all the queried data into a java object.
Game Rules: As the saying goes, nothing can work without rules. Especially for programs, it can only do things with rules, and it can’t do things without rules. Well, then
 A table object is a pojo class, and each field in the table corresponds to an attribute in the pojo class.
              And the name of the pojo class is the same as the name of the table, the attribute name and the field name are the same, the case does not matter, because the database is generally not case-sensitive
      2) Add standard set and get methods for each attribute in the pojo class.
With the rules of the game, let’s start the game.

1. First, there is a table in the database. Assume that the database name is: blogsystem, and a table name in it is userinfo. As shown in the picture:




2. Create the corresponding pojo class:

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 obtain 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 the dao class that operates the database Java reflection mechanism

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 {
    /**
     * 解析出保存对象的sql语句
     *
     * @param object
     *            :需要保存的对象
     * @return:保存对象的sql语句
     */
    public static String getSaveObjectSql(Object object) {
        // 定义一个sql字符串
        String sql = "insert into ";
        // 得到对象的类
        Class c = object.getClass();
        // 得到对象中所有的方法
        Method[] methods = c.getMethods();
        // 得到对象中所有的属性
        Field[] fields = c.getFields();
        // 得到对象类的名字
        String cName = c.getName();
        // 从类的名字中解析出表名
        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("字段名字----->" + fieldName);
                try {
                    Object value = method.invoke(object, null);
                    System.out.println("执行方法返回的值:" + value);
                    if (value instanceof String) {
                        vList.add("\"" + value + "\"");
                        System.out.println("字段值------>" + 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;
 
    }
 
    /**
     * 将对象保存到数据库中
     *
     * @param object
     *            :需要保存的对象
     * @return:方法执行的结果;1:表示成功,0:表示失败
     */
    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;
        }
    }
 
    /**
     * 从数据库中取得对象
     *
     * @param arg0
     *            :对象所属的类
     * @param id
     *            :对象的id
     * @return:需要查找的对象
     */
    public Object getObject(String className, int Id) {
        // 得到表名字
        String tableName = className.substring(className.lastIndexOf(".") + 1,
                className.length());
        // 根据类名来创建Class对象
        Class c = null;
        try {
            c = Class.forName(className);
 
        } catch (ClassNotFoundException e1) {
 
            e1.printStackTrace();
        }
        // 拼凑查询sql语句
        String sql = "select * from " + tableName + " where Id=" + Id;
        System.out.println("查找sql语句:" + sql);
        // 获得数据库链接
        Connection con = Connect2DBFactory.getDBConnection();
        // 创建类的实例
        Object obj = null;
        try {
 
            Statement stm = con.createStatement();
            // 得到执行查寻语句返回的结果集
            ResultSet set = stm.executeQuery(sql);
            // 得到对象的方法数组
            Method[] methods = c.getMethods();
            // 遍历结果集
            while (set.next()) {
                obj = c.newInstance();
                // 遍历对象的方法
                for (Method method : methods) {
                    String methodName = method.getName();
                    // 如果对象的方法以set开头
                    if (methodName.startsWith("set")) {
                        // 根据方法名字得到数据表格中字段的名字
                        String columnName = methodName.substring(3,
                                methodName.length());
                        // 得到方法的参数类型
                        Class[] parmts = method.getParameterTypes();
                        if (parmts[0] == String.class) {
                            // 如果参数为String类型,则从结果集中按照列名取得对应的值,并且执行改set方法
                            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 about the effect of starting the test:

package cn.netjava.tester;
 
import cn.netjava.pojo.UserInfo;
import cn.netjava.session.NetJavaSession;
 
public class Tester {
    public static void main(String args[]) {
        //获得NetJavaSession对象
        NetJavaSession session = new NetJavaSession();
        //创建一个UserInfo对象
        UserInfo user = new UserInfo();
        //设置对象的属性
        user.setId(6988);
        user.setAge(44);
        user.setPwd("pwd");
        user.setName("champion");
        //将对象保存到数据库中
        String sql = session.getSaveObjectSql(user);
        System.out.println("保存对象的sql语句:" + sql);
        //查找对象
        UserInfo userInfo = (UserInfo) session.getObject(
                "cn.netjava.pojo.UserInfo", 6988);
        System.out.println("获取到的信息:" + userInfo);
 
    }
}

5. Printed results:

7. Summary

Generally speaking, the Java reflection mechanism is a very useful thing, and it can solve many problems. Because the reflection mechanism is very flexible, with it, we don’t need to spend too much time writing code to operate the database, but spend more time on the logical functions of the project. This can be very It greatly reduces development time and makes the code more readable. Many existing open source frameworks use reflection mechanisms. They only need to configure files and then call their methods according to rules.

Java reflection mechanism

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn