java reflection knowledge

Keywords: Java JDBC Attribute SQL

reflex

Article directory


Summary

Definition

JAVA reflection mechanism is in the running state, for any class, can know all the attributes and methods of this class; for any object, can call any method and attributes of it; this dynamic acquisition of information and dynamic invocation of object methods is called the reflection mechanism of Java language.

purpose

In the daily development of third-party applications, we often encounter a class whose member variables, methods or attributes are private or open to system applications. At this time, we can use Java reflection mechanism to obtain the required private members or methods by reflection. Of course, not all of them are suitable for reflection. In a previous case, the results obtained by reflection are not in accordance with expectations. Reading the source code, we find that after layer-by-layer invocation, the permission of the application is checked in the place where the final result is returned. For the application without permission, the return value is meaningless default value, otherwise, the return of the actual value will protect the privacy of the user.

Relevant Classes of Reflection Mechanisms

The classes related to Java reflection are as follows:

Class name purpose
Class Class Entities representing classes, representing classes and interfaces in running Java applications
Class Field Member variables representing classes (member variables are also called class attributes)
Class Method The Method of Representing Classes
Constructor class Construction Method of Representative Class

Class Class

Class Entities representing classes represent classes and interfaces in running Java applications. There are many useful methods in this class. Here is a brief introduction to their classification.

  • Methods for obtaining class correlation
Method purpose
asSubclass(Class clazz) Converting the object of the passed class to the object representing its subclass
Cast Converting objects into objects representing classes or interfaces
getClassLoader() Get the loader for the class
getClasses() Returns an array containing objects of all common and interface classes in that class
getDeclaredClasses() Returns an array containing objects of all classes and interface classes in that class
forName(String className) Return the object of the class according to the class name
getName() Get the full path name of the class
newInstance() Create instances of classes
getPackage() Get the package of the class
getSimpleName() Get the name of the class
getSuperclass() Get the name of the parent class inherited by the current class
getInterfaces() Get the class or interface that the current class implements
  • A Method of Obtaining Attribute Relevance in Classes
Method purpose
getField(String name) Get a public property object
getFields() Get all public property objects
getDeclaredField(String name) Get an attribute object
getDeclaredFields() Get all attribute objects
  • Method of Obtaining Annotation Relevance in Classes
Method purpose
getAnnotation(Class annotationClass) Returns the public annotation object in this class that matches the parameter type
getAnnotations() Returns all public annotation objects of this class
getDeclaredAnnotation(Class annotationClass) Returns all annotation objects in this class that match the parameter type
getDeclaredAnnotations() Returns all comment objects of this class
  • Getting constructor-related methods in classes
Method purpose
getConstructor(Class...<?> parameterTypes) Obtaining the public construction method matching the parameter type in this class
getConstructors() Obtain all public constructions of this class
getDeclaredConstructor(Class...<?> parameterTypes) Obtain the construction method of matching parameter type in this class
getDeclaredConstructors() Obtain all construction methods of this class
  • Obtaining method-related methods in classes
Method purpose
getMethod(String name, Class...<?> parameterTypes) Getting a public method of this kind
getMethods() Obtain all public methods of this class
getDeclaredMethod(String name, Class...<?> parameterTypes) Get a method of this kind
getDeclaredMethods() Obtain all methods of this class
  • Other important methods in classes
Method purpose
isAnnotation() Returns true if it is a comment type
isAnnotationPresent(Class<? extends Annotation> annotationClass) Returns true if it is a specified type annotation type
isAnonymousClass() Returns true if it is an anonymous class
isArray() Returns true if it is an array class
isEnum() If it is an enumerated class, it returns true
isInstance(Object obj) Returns true if obj is an instance of this class
isInterface() If it is an interface class, return true
isLocalClass() Returns true if it is a local class
isMemberClass() If it is an internal class, return true

Class Field

Field A member variable representing a class (a member variable is also called a class attribute).

Method purpose
equals(Object obj) Property equal to obj returns true
get(Object obj) Get the corresponding attribute values in obj
set(Object obj, Object value) Setting the corresponding property values in obj

Class Method

Method Methods representing classes.

Method purpose
invoke(Object obj, Object... args) Pass object object object and parameter to call corresponding method of object

Constructor class

Constructor The construction method of representative class.

Method purpose
newInstance(Object... initargs) Create class objects based on passed parameters

1. Several Ways to Get Class Objects

 /**
 * Three Ways to Get Class Objects
 * 1 Object -> getClass();
 * 2 Any data type (including basic data types) has a "static" class attribute
 * 3 Through the static method of Class class: forName (String className) (commonly used)
 *
 */

Student object

package com.ooyhao.reflection.bean;
import java.io.Serializable;
public class Student implements Serializable {
    public Integer id;
    private String name;
    private String sex;
    private Integer age;
    public Student() {}
    public Student(String name){
        this.name = name;
    }
    public Student(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    public Student(Integer id, String name, String sex, Integer age) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    protected Student(Integer id,String name){
        this.name = name;
    }
    private Student(Integer id){
        this.id = id;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    private String printInfo(String message){
        System.out.println("Just for demonstration.:"+message);
        this.name = message;
        return message;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

Several Methods of Obtaining Class Objects

@Test
public void getClassFun() throws ClassNotFoundException {
    /**
     * Way 1: Use the getClass() method of the object to get the Class object
     *  Note: Since there are already objects, it is not very meaningful (not often used) to obtain Class through objects.
     * */
    Student student = new Student();
    Class<?> aClass = student.getClass();
    System.out.println(aClass);

    /**
     * Way 2: Get Class Objects by Class Attributes of Classes
     * Description: You need to import a complete package name, which is highly dependent. If you do not import a package, you will report compilation exceptions (not commonly used).
     * */
    Class<Student> studentClass = Student.class;
    System.out.println(studentClass);


    /**
    * Mode 3: Use forName() method of Class class to get Class object through complete package name + class name
    * Note: No need to import package names, class names, or create objects (recommendation)
    * Generally, there is a third way, a string can be passed in or written in the configuration file, and many other methods.
    * */
    Class<?> forName = Class.forName("com.ooyhao.reflection.bean.Student");
    System.out.println(forName);

}

//Output results:
class com.ooyhao.reflection.bean.Student
class com.ooyhao.reflection.bean.Student
class com.ooyhao.reflection.bean.Student

2. Get the construction method and use it

1. Obtain the construction method:
  1. Batch method:
public Constructor[] getConstructors(): All "public" construction methods
            Public Constructor [] getDeclared Constructors (): Get all constructions (private, protected, default, public)
     
  2. Get a single method and call:
public Constructor getConstructor(Class... ParameterTypes: Get a single "public" constructor:
Public Constructor getDeclared Constructor (Class... ParameterTypes: Getting "a constructor" can be private, protected, default, and public;

  Call the constructor:
Constructor–>newInstance(Object... initargs)

2. newInstance is the method of Constructor class (the class that manages constructors)
The api is interpreted as:
newInstance(Object... initargs)
           Use the constructor represented by this Constructor object to create a new instance of the declarative class of the constructor and initialize the instance with the specified initialization parameters.
Its return value is of type T, so newInstance is a new instance object that creates a declarative class of constructors. And call for it

Case demonstration:

@Test
public void testConstructor() throws Exception{

    Class<?> aClass = Class.forName("com.ooyhao.reflection.bean.Student");
    /*Get all public-modified constructors*/
//        Constructor<?>[] constructors = aClass.getConstructors();
    /*Get all constructors (private,protected,default,public)*/
    Constructor<?>[] constructors = aClass.getDeclaredConstructors();
    for (Constructor constructor : constructors){
        System.out.println(constructor);
        Class[] parameterTypes = constructor.getParameterTypes();
        for (Class c : parameterTypes){
            System.out.println(c);
        }
        System.out.println("-----------------");
    }

    /*Get a common, parameterized constructor*/
    Constructor<?> constructor = aClass.getConstructor(null);
    //public com.ooyhao.reflection.bean.Student()
    System.out.println(constructor);


    Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(Integer.class);
    //private com.ooyhao.reflection.bean.Student(java.lang.Integer)
    System.out.println(declaredConstructor);


    declaredConstructor.setAccessible(true);//Violent access (ignoring access modifiers)
    Object o = declaredConstructor.newInstance(12);
    Student student = (Student) o;
    //student:Student{id=12, name='null', sex='null', age=null}
    System.out.println("student:"+student);

}

//Operation results:
private com.ooyhao.reflection.bean.Student(java.lang.Integer)
class java.lang.Integer
-----------------
protected com.ooyhao.reflection.bean.Student(java.lang.Integer,java.lang.String)
class java.lang.Integer
class java.lang.String
-----------------
public com.ooyhao.reflection.bean.Student(java.lang.Integer,java.lang.String,java.lang.String,java.lang.Integer)
class java.lang.Integer
class java.lang.String
class java.lang.String
class java.lang.Integer
-----------------
public com.ooyhao.reflection.bean.Student()
-----------------
public com.ooyhao.reflection.bean.Student(java.lang.String)
class java.lang.String
-----------------
public com.ooyhao.reflection.bean.Student(java.lang.String,java.lang.Integer)
class java.lang.String
class java.lang.Integer
-----------------
public com.ooyhao.reflection.bean.Student()
private com.ooyhao.reflection.bean.Student(java.lang.Integer)
student:Student{id=12, name='null', sex='null', age=null}

3. Get member variables and call them

/* 
 * Get member variables and call: 
 *  
 * 1. Batch 
 * 1).Field[] getFields(): Get all the "public fields" 
 * Field [] getDeclared Fields (): Get all fields, including: private, protected, default, public; 
 * 2. Obtain a single: 
 *1).public Field getField(String fieldName): get a "public" field; 
 * 2. Public Field getDeclared Field (String field Name): Get a field (which can be private) 
 *  
 * Set the value of the field: 
 *      Field –> public void set(Object obj,Object value): 
 * Description of parameters: 
 * 1.obj: The object of the field to be set; 
 * 2.value: The value to be set for the field; 
 */  

Case demonstration:

@Test
public void testField() throws Exception{

    Class<?> aClass = Class.forName("com.ooyhao.reflection.bean.Student");
    System.out.println("----------Obtain public attribute----------");
    Field[] fields = aClass.getFields();
    for (Field field : fields){
        System.out.println(field);
    }
    System.out.println("----------Obtain public,default,protected,private attribute----------");
    Field[] declaredFields = aClass.getDeclaredFields();
    for (Field field : declaredFields){
        System.out.println(field);
    }

    /*Setting the value of the property by reflection*/
    System.out.println("------Setting the value of the property by reflection------");
    Object o = aClass.newInstance();
    Field name = aClass.getDeclaredField("name");
    name.setAccessible(true);
    name.set(o,"Ouyang Hao");
    Student student = (Student) o;
    System.out.println(student);
}

//Operation results:
----------Obtainpublicattribute----------
public java.lang.Integer com.ooyhao.reflection.bean.Student.id
----------Obtainpublic,default,protected,privateattribute----------
public java.lang.Integer com.ooyhao.reflection.bean.Student.id
private java.lang.String com.ooyhao.reflection.bean.Student.name
private java.lang.String com.ooyhao.reflection.bean.Student.sex
private java.lang.Integer com.ooyhao.reflection.bean.Student.age
------Setting the value of the property by reflection------
Student{id=null, name='Ouyang Hao', sex='null', age=null}

4. Get member methods and call them

  
/* 
 * Get the member method and call: 
 *  
 * 1. Batch: 
 * public Method[] getMethods(): Get all public methods; (Methods that contain parent classes also contain Object classes) 
 * public method [] getDeclared Methods (): Get all member methods, including private (excluding inheritance) 
 * 2. Obtain a single: 
 *      public Method getMethod(String name,Class<?>... parameterTypes): 
 * Parameters: 
 * Name: Method name; 
 * Class... Class type object with formal parameters 
 *      public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 
 *  
 * Call method: 
 *      Method –> public Object invoke(Object obj,Object... args): 
 * Description of parameters: 
 * obj: The object of the method to be invoked; 
 * args: The argument passed when invoking the method; 
 */  

Case demonstration:

@Test
public void testMethod() throws Exception{

    Class<?> aClass = Class.forName("com.ooyhao.reflection.bean.Student");
    System.out.println("----------Obtain public Member method----------");
    Method[] methods = aClass.getMethods();
    for (Method method : methods){
        System.out.println(method);
    }

    Method[] declaredMethods = aClass.getDeclaredMethods();
    System.out.println("----------Obtain public,default,protected,private Member method----------");
    for (Method method : declaredMethods){
        System.out.println(method);
    }
    /*Getting the setName method*/
    System.out.println("----------Obtain printInfo Method----------");
    Method printInfo = aClass.getDeclaredMethod("printInfo", String.class);
    System.out.println(printInfo);
//        Object o1 = aClass.newInstance();
    printInfo.setAccessible(true);//Release of Private Limitation
    Object o = aClass.getConstructor().newInstance();
    Object ouYang = printInfo.invoke(o, "ouYangHao");
    //The object Student object is returned. Student{id=null, name='ouYangHao', sex='null', age=null}
    System.out.println("Participants:"+o);
    //What is returned is the return value of the method. ouYangHao
    System.out.println("Method return value:"+ouYang);
}

//Operation results:
----------ObtainpublicMember method----------
public java.lang.String com.ooyhao.reflection.bean.Student.toString()
public java.lang.String com.ooyhao.reflection.bean.Student.getName()
public java.lang.Integer com.ooyhao.reflection.bean.Student.getId()
public void com.ooyhao.reflection.bean.Student.setName(java.lang.String)
public java.lang.String com.ooyhao.reflection.bean.Student.getSex()
public void com.ooyhao.reflection.bean.Student.setSex(java.lang.String)
public java.lang.Integer com.ooyhao.reflection.bean.Student.getAge()
public void com.ooyhao.reflection.bean.Student.setAge(java.lang.Integer)
public void com.ooyhao.reflection.bean.Student.setId(java.lang.Integer)
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 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()
----------Obtainpublic,default,protected,privateMember method----------
public java.lang.String com.ooyhao.reflection.bean.Student.toString()
public java.lang.String com.ooyhao.reflection.bean.Student.getName()
public java.lang.Integer com.ooyhao.reflection.bean.Student.getId()
public void com.ooyhao.reflection.bean.Student.setName(java.lang.String)
private java.lang.String com.ooyhao.reflection.bean.Student.printInfo(java.lang.String)
public java.lang.String com.ooyhao.reflection.bean.Student.getSex()
public void com.ooyhao.reflection.bean.Student.setSex(java.lang.String)
public java.lang.Integer com.ooyhao.reflection.bean.Student.getAge()
public void com.ooyhao.reflection.bean.Student.setAge(java.lang.Integer)
public void com.ooyhao.reflection.bean.Student.setId(java.lang.Integer)
----------Obtain printInfo Method----------
private java.lang.String com.ooyhao.reflection.bean.Student.printInfo(java.lang.String)
//Just for demonstration.:ouYangHao
//Object: Student{id=null, name='ouYangHao', sex='null', age=null}
//Method return value: ouYangHao

5. Reflection calls main method

@Test
public void testMain() throws Exception {
    //1. Getting bytecode of Student object
    Class<?> aClass = Class.forName("com.ooyhao.reflection.test.MainFun");
    //2. Obtaining main method
    Method main = aClass.getMethod("main", String[].class);
    System.out.println(main);
    //3. Call main method
    main.invoke(null,(Object)new String[]{"a","b","c"});//Method 1
    String[] args = new String[]{"Java","SpringBoot","SpringCloud","Dubbo","Zookeeper"};
    //The first parameter, object type, is null because the method is static.
    //The second parameter is the String array. Note that when jdk1.4 is an array, after jdk1.5 is a variable parameter.
    //new String[]{"a","b","c"} is split into three objects. So we need to turn it around.
    main.invoke(null,new Object[]{args});//Method two
}

//Operation results:
public static void com.ooyhao.reflection.test.MainFun.main(java.lang.String[])
----------implement main Method----------
main Method parameters:[a, b, c]
----------implement main Method----------
main Method parameters:[Java, SpringBoot, SpringCloud, Dubbo, Zookeeper]

6. Return to skip generic checking

@Test
public void testGenetic() throws Exception {

    List<String> list = new ArrayList<String>();
    list.add("Java");

    Class<?> aClass = list.getClass();
    Method add = aClass.getMethod("add", Object.class);
    add.invoke(list,100);

    for (Object o : list){
        System.out.println(o);
    }
}

//Operation results:
Java
100

Mapping Objects and Tables Using Annotations and Reflections

1. notes

1.@Entity

package com.ooyhao.jdbc.annotation;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
    public String value();//tableName
}

2.@Column

package com.ooyhao.jdbc.annotation;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    public String value();//Column names
}

3.@IsExist

package com.ooyhao.jdbc.annotation;


import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IsExist {
    public boolean value();//Does it exist?
}

2.User Bean

package com.ooyhao.jdbc.bean;

import com.ooyhao.jdbc.annotation.Column;
import com.ooyhao.jdbc.annotation.Entity;
import com.ooyhao.jdbc.annotation.IsExist;

import java.io.Serializable;
import java.util.Date;

@Entity("sys_user")
public class User implements Serializable {

    @Column("id")
    private Long id;

    @Column("username")
    private String username;

    @Column("password")
    private String password;

    @Column("create_time")
    private Date createTime;

    @Column("create_user")
    private String createUser;

    @Column("modify_time")
    private Date modifyTime;

    @Column("modify_user")
    @IsExist(true)
    private String modifyUser;

    public User() {}

    public Long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getCreateUser() {
        return createUser;
    }

    public void setCreateUser(String createUser) {
        this.createUser = createUser;
    }

    public Date getModifyTime() {
        return modifyTime;
    }

    public void setModifyTime(Date modifyTime) {
        this.modifyTime = modifyTime;
    }

    public String getModifyUser() {
        return modifyUser;
    }

    public void setModifyUser(String modifyUser) {
        this.modifyUser = modifyUser;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", createTime=" + createTime +
                ", createUser='" + createUser + '\'' +
                ", modifyTime=" + modifyTime +
                ", modifyUser='" + modifyUser + '\'' +
                '}';
    }
}

3.DBHelper

package com.ooyhao.jdbc.helper;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DbHelper {

    public static final String URL = "jdbc:mysql://120.79.167.XXX:3306/GD?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&useSSL=false";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "XXXXXXXX";
    public static final String DRIVER = "com.mysql.jdbc.Driver";


    public static Connection getConnection(){
        try{
            Class.forName(DRIVER);
            Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            return connection;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    public static void close(Connection connection, Statement statement, ResultSet resultSet){
        try{
            if (connection != null){
                connection.close();
            }
            if (statement != null){
                statement.close();
            }
            if (resultSet != null){
                resultSet.close();
            }

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

    public static void close(Connection connection, Statement statement){
        try{
            if (connection == null){
                connection.close();
            }
            if (statement != null){
                statement.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

4.IJdbcDao

package com.ooyhao.jdbc.jdbc;

import com.ooyhao.jdbc.annotation.Column;
import com.ooyhao.jdbc.annotation.Entity;
import com.ooyhao.jdbc.annotation.IsExist;
import com.ooyhao.jdbc.helper.DbHelper;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class IJdbcDao {

    public <T> List<T> selectDataToBean(Class<T> tClass) {
        List<T> list = new ArrayList<>();
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            String simpleName = tClass.getSimpleName();
            String tableName = String.valueOf(simpleName.charAt(0)).toLowerCase() + simpleName.substring(1);
            boolean annotationPresent = tClass.isAnnotationPresent(Entity.class);
            if (annotationPresent){
                Entity entity = tClass.getAnnotation(Entity.class);
                tableName = entity.value();
            }
            String sql = " select * from "+tableName;

            connection = DbHelper.getConnection();

            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();

            Field[] fields = tClass.getDeclaredFields();

            Map<String,Field> map = new HashMap<>();
            for (Field field : fields){

                String columnValue = null;
                if (field.isAnnotationPresent(Column.class)){
                    Column column = field.getAnnotation(Column.class);
                    columnValue = column.value();
                }
                boolean isExistValue = true;
                if (field.isAnnotationPresent(IsExist.class)){
                    IsExist isExist = field.getAnnotation(IsExist.class);
                    isExistValue = isExist.value();
                }
                if (isExistValue){
                    map.put(columnValue,field);
                }
            }
            int colCount = resultSet.getMetaData().getColumnCount();
            while (resultSet.next()){

                T t = tClass.newInstance();
                for (int i = 1; i <= colCount; i++) {
                    String columnLabel = resultSet.getMetaData().getColumnLabel(i);
                    Field field = map.get(columnLabel);
                    if (field != null){
                        field.setAccessible(true);
                        field.set(t,resultSet.getObject(i));
                    }
                }
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DbHelper.close(connection,preparedStatement,resultSet);
        }
        return list;
    }
}

5. Tests and results

public class App {
    public static void main(String[] args) {
        IJdbcDao iJdbcDao = new IJdbcDao();
        List<User> users = iJdbcDao.selectDataToBean(User.class);
        for (User user : users){
            System.out.println(user);
        }
    }
}

//Result:
User{id=1, username='admin', password='1', createTime=2019-01-23 17:24:24.0, createUser='admin', modifyTime=2019-01-23 17:24:24.0, modifyUser='admin'}
User{id=2, username='jack', password='1', createTime=2019-01-23 17:24:28.0, createUser='admin', modifyTime=2019-01-23 17:24:24.0, modifyUser='admin'}
User{id=8, username='23', password='null', createTime=2019-01-25 10:51:57.0, createUser='admin', modifyTime=2019-01-25 10:51:57.0, modifyUser='admin'}
User{id=3, username='Lin Daiyu', password='123456', createTime=2019-01-23 17:29:56.0, createUser='admin', modifyTime=2019-01-23 17:29:56.0, modifyUser='admin'}
User{id=4, username='Jia Baoyu', password='123456', createTime=2019-01-23 17:30:24.0, createUser='admin', modifyTime=2019-01-23 17:30:24.0, modifyUser='admin'}
User{id=6, username='ouYang', password='123456', createTime=2019-01-23 17:30:47.0, createUser='admin', modifyTime=2019-01-23 17:30:47.0, modifyUser='admin'}

Reflection mechanism

Class is used to describe a group of objects, and reflection mechanism is used to describe a group of classes. It can be compared with File.

Use Class class, Field class, Method class, Constructor class, Package class to describe any class.

Class: Used to describe the class itself.

Package: The package used to describe the class belongs to.

Field: Used to describe attributes in a class.

Method: The method used to describe a class.

Constructor: Describes how classes are constructed.

Annotation: Used to describe annotations in classes.

1. Common methods in Class

  1. int result = clazz.getModifiers(); Gets the modifier of the class (permissions, features)

  2. String name = clazz.getName(); get name (full class name)

  3. String simpleName = clazz.getSimpleName(); Gets a simple class name

  4. Package P = clazz. getPackage (); (getName method in package class) p.getName(); get package / package name

  5. Class claz = clazz.getSuperClass(); Gets the superclass

  6. Class[] clazzes = clazz.getInterfaces(); Gets the interface class

  7. Class[] clazzes = clazz.getClasses(); the internal class in the capture class (public) is not available for private internal classes.

  8. Object obj = clazz.newInstance(); the default invocation of the parametric constructor creates the object. If no parametric constructor exists, an exception will be thrown.

    • Throw NoSuchMethodException.
  9. Field nameField = clazz.getField("name"); gets a Field named name. (get name attribute, only public, including parent)

  10. Field[] fields = clazz.getFields(); gets all fields. (Gets all public fields, including parent classes)

  11. Field nameField = class.getDeclaredField("name"). (Getting the name attribute, whether private or shared, can only get this class)

  12. Field[] fields = clazz.getDeclaredFields(); gets all attributes. Only accessible to this class

  13. Method = clazz. getMethod ("method name", "Class... Parameter list; get public methods (own class + parent class)

  14. Method[] ms = clazz.getMethods(); Get all public methods (own class + parent class)

  15. Method = clazz. getDeclared Method ("method name", "Class... Parameter list; access method (public + private, only access to this class)

  16. Method [] methods = clazz. getDeclared Methods (); get all methods (public + private, only this class)

  17. Constructor c = clazz.getConstructor(Class... Parameter type; Get construction method

  18. Constructor[] cs = clazz.getConstructors(); Gets all public constructors

  19. Constructor C = clazz. getDeclared Constructor (Class... Parameter Type; Getting Private + Public Construction Method

  20. Constructor [] CS = clazz. getDeclared Constructors (); gets all private + public constructors.

2. Common methods in Field classes

  • int result = f.getModifiers(); gets the modifier.
  • Class clazz = f.getType(); Gets the type of attribute.
  • String name = f.getName(); Gets the attribute name

Operational attributes

Set the value of the property

NameField. set (object, attribute value); for example: nameField.set(student, "ouYang");

Get the value of the attribute

Object field Value = field. get (object); for example, String name = String nameField. get (student);

Access privileges need to be opened to assign/value private attributes

field.setAccessible(true). Indicates that private attributes can be manipulated directly

We know that the content and length of String strings can't be changed, but they can be changed by reflection.

@Test
public void testString() throws NoSuchFieldException, IllegalAccessException {
    String s = "abc";
    Field value = s.getClass().getDeclaredField("value");
    value.setAccessible(true);

    char[] o = (char[]) value.get(s);
    o[0] = 'Europe';
    o[1] = 'Yang';
    o[2] = 'Hao';
    System.out.println(o);
    value.set(s,o);
    System.out.println(s);

}

3. Common methods of Method class

  • int result = m.getModifiers(); gets the modifier. (Authority + Characteristics)
  • Class mothedReturnType = m.getReturnType(); Gets the data type of the return value.
  • String methodName = m.getName(); gets the name of the method.
  • Class[] mpts = m.getParameterTypes(); gets the type of the method parameter list.
  • Class[] mets = m.getExceptionTypes(); Gets the exception type thrown by the method.

Call method, execute method

If it is not found, a NoSuchMethodException is thrown.

Class pClass = Person.class;

Method m = p.getMethod("eat",String.class);The list of parameters is a variable parameter, and the parameters of the representation are01...A parameter.

Object o = m.invoke(p,"Having dinner");If the method invoked has parameters, the parameters need to be passed in, and if the method has a return value, the playback value can be received.

Specific code examples can refer to the example code above.

If the method is private and access is not allowed, access permissions need to be set.

m.setAccessible(true);

4.Constructor Construction Method

  • int result = c.getModifiers(); Gets the modifier for the constructor
  • String name = c.getName(); gets the name of the constructor
  • Class[] classes = c.getParameterTypes(); Gets the parameter type of the constructor
  • Class[] classes = c.getExceptionTypes(); Gets the exception type of the constructor

Operational Construction Method

Create objects (new Instance (Class... Parametric type)

  • Create objects using a parametric-free construction method.
Class clazz = Person.class;
Constructor c = clazz.getConstructor();
Person p = (Person)c.newInstance();
  • Objects are created using a parametric construction method.
Class clazz = Person.class;
Constructor c = clazz.getConstructor(String.name,Integer.class);
Person p = (Peroson)c.newInstance("ouYang",23);
System.out.println(p);

class Person{
  private String name;
  private Integer age;
  public Person(String name,Integer age){
    this.name = name;
    this.age = age;
  }
}
Examples of project application:
package com.global.struct.persistence.dbutils.transformer;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.global.struct.core.exception.StructRuntimeException;

public class ExtendedBeanListHandler<T> extends BeanListHandler<T> {

	private Class<T> resultClass;
	
	public ExtendedBeanListHandler(Class<T> type) {
		super(type);
		this.resultClass = type;
	}

	@Override
	public List<T> handle(ResultSet rs) throws SQLException {
		List<T> list = new ArrayList<T>();
		try {
			ResultSetMetaData rsmd = rs.getMetaData();
			while(rs.next()){
				T result = resultClass.newInstance();
				int cols = rsmd.getColumnCount();
					for (int col = 1; col <= cols; col++) {
					String columnName = rsmd.getColumnLabel(col);
					if (null == columnName || 0 == columnName.length()) {
						columnName = rsmd.getColumnName(col);
					}
					String aliase = columnName;
					String[] aliaseTmp = aliase.split("\\_");
					StringBuffer sbAlise = new StringBuffer();
					for (int j = 0; j < aliaseTmp.length; j++) {
						String alstr = aliaseTmp[j];
						if (j != 0) {
							alstr = String.valueOf(alstr.charAt(0)).toUpperCase()
									+ alstr.substring(1);
						}
						sbAlise.append(alstr);
					}
					Field field = null;
					try {
						field = resultClass.getDeclaredField(sbAlise.toString());
					} catch (NoSuchFieldException e) {
						continue;
					}
					field.setAccessible(true);
					String fieldType = field.getType().getSimpleName();
					Object fieldVal = rs.getObject(columnName);
					if (fieldVal != null) {
						String type = rsmd.getColumnTypeName(col);
						if (fieldType.equals("Long")) {
							fieldVal = Long.valueOf(fieldVal.toString());
						} else if (fieldType.equals("String")) {
							fieldVal = String.valueOf(fieldVal);
						} else if (fieldType.equals("Integer")) {
							if (type.equals("Boolean")) {
								boolean tmpVal = (Boolean) fieldVal;
								fieldVal = tmpVal ? 1 : 0;
							}else {
								fieldVal = Integer.valueOf(fieldVal.toString());
							}
						} else if(fieldType.equals("Boolean")){
							if(!(fieldVal!=null&&fieldVal instanceof Boolean)) {
								if(fieldVal!=null&&(fieldVal.toString().equals("1"))){
									fieldVal = true;
								}else {
									fieldVal = false;
								}
							}
						}
						
					}
					if(fieldType.equals("Double")){
						try {
							field.set(result, fieldVal);
						} catch (Exception e) {
							field.set(result, Double.valueOf(fieldVal.toString()));
						}
					}else{
						field.set(result, fieldVal);
					}
				}
				list.add(result);
			}
		} catch (Exception e) {
			throw new StructRuntimeException("dbutils sql to bean fail",e);
		}
		return list;
	}
}

Last

If you feel good, then pay attention to Xiaobian Oh! Communicate and learn together

Posted by wmguk on Sun, 22 Sep 2019 04:16:45 -0700