1. What is the reflection mechanism?
Simply put, the reflection mechanism means that the program can obtain its own information while running. In Java, as long as the name of the class is given, all information about the class can be obtained through the reflection mechanism.
2. Where is the reflection mechanism used?
Sometimes, we have used some knowledge, but we don't know what the 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: The type is determined at compile time and the object is bound, that is, passed.
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 them, which shows 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 reinstall it. 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. 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 its impact on performance. Using reflection is basically an interpreted operation where 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?
In a word, it can get whatever information there is in the class, but the prerequisite is to know the name of the class, otherwise there will be no further information. First, the Class object must be created based on the full name of the incoming class.
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 an object, everything is easy to handle. 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 public constructors
Constructor getDeclaredConstructor(Class[] params)//Get public and non-public constructors based on specified parameters
Constructor[] getDeclaredConstructors()//Get all public constructors
Get method of class method
Method getMethod(String name, Class[] params), get the method based on the method name and parameter type
Method[] getMethods()//Get all public methods
Method getDeclaredMethod(String name, Class[] params)//According to the method name and parameter type, obtain public and non-public methods
Method[] getDeclaredMethods()//Get all public and non-public methods
How to get attributes in a 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 based on method name
Field[] getDeclaredFields()//Get all public and non-public methods in the class
These are the commonly used ones. If you know these, everything else will be easy to handle...
5. What can be done with the reflection mechanism?
When I first started using jdbc, I felt like vomiting when I wrote to access the database. 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 wrote about different Create different DAO classes in the table, which not only speeds up development, but also makes the code redundant. The most terrible thing is that they look almost the same, and then directly copy and modify them, because it is easy to make various low-level mistakes (upper and lower case, one more or One letter is missing...), one mistake can take you a long time to find.
With the Java reflection mechanism, everything is easy to handle. You only need to write a dao class with four methods, add, delete, modify, and query, and pass in different objects. It is OK. There is no need to create a dao class for each table. The reflection mechanism will It automatically does the rest for us, that's its benefit. To put it bluntly, the reflection mechanism is designed to help us do repetitive and regular things, so many software that automatically generates code now uses the reflection mechanism to complete it. As long as you enter the relevant parameters according to the rules, low-level programmers are slow The slow ones were obliterated, why? Because there is no need to write code, anyone can develop it, so why do programmers do it? So we have only one way out, and that is to work hard and work harder, become a senior programmer, specialize in developing stupid software, and let other programmers go aside and cool off, haha~
6. Example of using reflection mechanism to add and check database data
Basic principle: when saving data, take out all the attribute values of the objects that need to be saved and then put together the SQL statement for query, and package all the queried data into a java object.
Rules of the game: As the saying goes, there is nothing without rules. Especially for programs, it can only do things with rules. It cannot do things without rules. Okay, let’s set the rules first.
1) Each table object in the database has a pojo class, and each field in the table corresponds to an attribute in the pojo class. Moreover, the name of the pojo class is the same as the name of the table, and the attribute name and 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 playing.
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:
Copy the code code as follows:
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 a factory class to obtain the database connection:
Copy the code code as follows:
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, writing the dao class that operates the database
Copy the code code as follows:
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 {
/**
* Parse out the sql statement that saves the object
*
* @param object
*: Object that needs to be saved
* @return: sql statement to save the object
*/
public static String getSaveObjectSql(Object object) {
//Define a sql string
String sql = "insert into ";
// Get the class of the object
Class c = object.getClass();
// Get all methods in the object
Method[] methods = c.getMethods();
// Get all properties in the object
Field[] fields = c.getFields();
// Get the name of the object class
String cName = c.getName();
// Parse 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("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("Field value------>" + 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;
}
/**
* Save the object to the database
*
* @param object
*: Object that needs to be saved
* @return: The result of method execution; 1: indicates success, 0: indicates failure
*/
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;
}
}
/**
* Get the object from the database
*
* @param arg0
*: The class to which the object belongs
* @param id
*: id of the object
* @return: the object to be found
*/
public Object getObject(String className, int Id) {
// Get the table name
String tableName = className.substring(className.lastIndexOf(".") + 1,
className.length());
//Create Class object based on class name
Class c = null;
try {
c = Class.forName(className);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
// Piece together the query sql statement
String sql = "select * from " + tableName + " where Id=" + Id;
System.out.println("Find sql statement: " + sql);
// Get database link
Connection con = Connect2DBFactory.getDBConnection();
//Create an instance of the class
Object obj = null;
try {
Statement stm = con.createStatement();
// Get the result set returned by executing the search statement
ResultSet set = stm.executeQuery(sql);
// Get the method array of the object
Method[] methods = c.getMethods();
// Traverse the result set
while (set.next()) {
obj = c.newInstance();
//Methods to traverse objects
for (Method method : methods) {
String methodName = method.getName();
// If the object's method starts with set
if (methodName.startsWith("set")) {
// Get the name of the field in the data table based on the method name
String columnName = methodName.substring(3,
methodName.length());
// Get the parameter type of the method
Class[] parmts = method.getParameterTypes();
if (parmts[0] == String.class) {
// If the parameter is of String type, obtain the corresponding value from the result set according to the column name, and execute the set method
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:
Copy the code code as follows:
package cn.netjava.tester;
import cn.netjava.pojo.UserInfo;
import cn.netjava.session.NetJavaSession;
public class Tester {
public static void main(String args[]) {
//Get the NetJavaSession object
NetJavaSession session = new NetJavaSession();
//Create a UserInfo object
UserInfo user = new UserInfo();
//Set 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("SQL statement to save the object: " + sql);
//Find object
UserInfo userInfo = (UserInfo) session.getObject(
"cn.netjava.pojo.UserInfo", 6988);
System.out.println("Information obtained: " + userInfo);
}
}
5. Printed results:
7. Let’s summarize
In general, the Java reflection mechanism is a very useful thing. It can solve many dead things because the reflection mechanism is very flexible. With it, we don’t need to spend too much time writing operations. Instead of using the database code, the method spends more time on the logical functions of the project. This can greatly reduce development time and make 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.