Reflection introduction and simple cases

Reflection overview: reflection is the soul of the frame!

1.1 JAVA reflection mechanism

In the running state, you can know all the properties and methods of any class; For any object, you can call any of its methods and properties; This function of dynamically obtaining information and dynamically calling object methods is called the reflection mechanism of java language.

You can get all the byte codes in the object class.

(class information: class name, package name, attribute, construction method, common method, inherited method)

​ p = new People();

​ ApplocationContext context = new ClassPathXmlApplocationContext("bean.xml");

​ context.getBean("id"); context.getBean(People.class); context.getBean("id",People.class);

reflection:

1. How to get the bytecode object of class?
2. How to obtain information in a class through bytecode objects?
3. How to use the information in the obtained object?

Now you need to use reflection!!!

Steps:

1. Get the bytecode object of the class
2.Extract information from class
3. Use class information

1.2 use of reflection

Java reflection mechanism to obtain class information is actually to obtain the contents of the bytecode file of the class and encapsulate these contents into a bytecode object, so we only need to use the reflected code to obtain the bytecode object to get the class information.

1.2.1 Class introduction

Class represents the entity of the class and represents the class and interface in the running Java application. There are many useful methods in this class. Here is a brief introduction to their classification.

  • Methods for obtaining Class related information

    Class.forName(""Full class name");
    object.getClass();	
    Class name.class;
    
  • Basic methods for obtaining information of classes:

    Method namemeaning
    getName()Get the full path name of the class
    newInstance()Create an instance of a class
    getPackage()Get the package of the class
    getSimpleName()Get the name of the class
    getSuperclass()Gets the name of the parent class that the current class inherits
    getInterfaces()Get the class or interface implemented by the current class
  • Get the methods related to the properties in the class

    Method namemeaning
    getField(String name)Get a public property object
    getFields()Get all public property objects
    getDeclaredField(String name)Get a property object
    getDeclaredFields()Get all attribute objects
  • Get the annotation related methods in the class

    Method namemeaning
    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 annotation objects of this class
  • Get constructor related methods in the class

    Method namemeaning
    getConstructor(Class...<?> parameterTypes)Get the public constructor matching the parameter type in this class
    getConstructors()Get all public constructors of this class
    getDeclaredConstructor(Class...<?> parameterTypes)Get the constructor matching the parameter type in this class
    getDeclaredConstructors()Get all construction methods of this class
  • Get the methods related to the methods in the class

Method namemeaning
getMethod(String name, Class<?>... parameterTypes)Get a public method of this class
getMethods()Get all public methods of this class
getDeclaredMethod(String name, Class<?>... parameterTypes)Get a method of this class
getDeclaredMethods()Get all methods of this class

1.2.2 get bytecode objects of classes - three methods

  • Get according to the full class name of the class

    Class.forName("Full class name");
    
  • Get bytecode object by class name

    Class name.class
    
  • Get bytecode object through instance object of class

    Class name variable name = new Class name();
    Variable name.getClass();
    
public static void main(String[] args) throws Exception {
        //Three ways
        //1.Class.forName("full class name"); Gets the bytecode object of the class through the class path
        Class pClass1 = Class.forName("com.aaa.reflex.demo1.People");
        System.out.println(pClass1);

        //2. Class name class
        Class pClass2 = People.class;
        System.out.println(pClass2);

        //3. Pass the object getClass();
        People people = new People();
        Class pClass3 = people.getClass();
        System.out.println(pClass3);

        System.out.println(pClass1 == pClass2);
        System.out.println(pClass1 == pClass3);
    }

**Note: * * the bytecode objects of the classes obtained by the three methods are the same.

1.2.3 obtain the class information according to the bytecode object of the class and use it.

  • Gets and calls the constructor of the class

    public void test1() throws Exception {
            //1. Get bytecode object of class
            Class pClass = People.class;
            //2. Obtain the construction information in the bytecode object
            Constructor constructor = pClass.getConstructor(int.class);
            System.out.println(constructor);
            //The instance object is created by calling the newInstance method through the constructor obtained from the bytecode object of the class and passing in the required parameters
            People o = (People) constructor.newInstance(5);
            System.out.println(o);
    
            Constructor constructor1 = pClass.getConstructor(int.class, String.class);
            System.out.println(constructor1);
    
            Constructor constructor2 = pClass.getConstructor(int.class, String.class, String.class);
            System.out.println(constructor2);
            //The instance object is created by calling the newInstance method through the constructor obtained from the bytecode object of the class and passing in the required parameters
            Object o1 = constructor2.newInstance(18, "Zhang San", "male");
            System.out.println(o1);
    
            //Get all public constructs
            Constructor[] constructors = pClass.getConstructors();
            System.out.println(Arrays.toString(constructors));
    
            //Get constructor without considering the modifier of construction
            //Single
            Constructor declaredConstructor = pClass.getDeclaredConstructor(String.class, String.class);
            System.out.println(declaredConstructor);
    
            //Get all constructors
            Constructor[] declaredConstructors = pClass.getDeclaredConstructors();
            System.out.println(Arrays.toString(declaredConstructors));
        
        	//pClass.newInstance();  By default, the null construction method without parameters is called
            Object o2 = pClass.newInstance();
            System.out.println(o2);
        }
    

    Note: the code bytecode object is used directly without obtaining the null structure without parameters newInstance(); The null structure without parameters is called by default.

  • Get and call the properties of the class

    Field class: field represents the member variable of the class (also known as the attribute of the class).

    methodmeaning
    get(Object obj)Get the corresponding attribute value in obj
    set(Object obj, Object value)Set the corresponding attribute value in obj
    setAccessible(boolean b)Ignore the permission modifier. If the member variable is private, it needs to be turned on
    public void test2() throws Exception{
            //1. Get bytecode object of class
            Class pClass = People.class;
            //2. Get the attribute information in the class
            // The Field class provides information about some operation properties
            //Get the variable / attribute of pulic modifier
            Field age = pClass.getField("age");
            System.out.println(age);
            Object o = pClass.newInstance();
            /*
            The object parameter obj needs to be passed in the set(Object obj,value) method to assign a value to the attribute
            obj : The attribute object parameter of which class this attribute is passed into the instance object of which class
             */
            age.set(o,18);
            System.out.println(o);
    
            //Get the properties of all Public modifiers
            Field[] fields = pClass.getFields();
            System.out.println(Arrays.toString(fields));
    
            /**
             * Get properties without considering modifiers
             */
            //single
            Field name = pClass.getDeclaredField("name");
            Object o1 = pClass.newInstance();
            //Ignore the permission modifier. Originally, the name attribute is private and cannot be assigned directly. setAccessible(true) must be turned on before assignment
            name.setAccessible(true);
            name.set(o1,"Zhang San");
            System.out.println(o1);
    
            //All
            Field[] declaredFields = pClass.getDeclaredFields();
            System.out.println(Arrays.toString(declaredFields));
        }
    
  • Get and call the normal method of the class

    The Method class represents the Method of the class

    methodpurpose
    invoke(Object obj, Object... args)Pass the object object and parameters and call the method corresponding to the object
    public void test3()throws Exception{
            //1. Get bytecode object of class
            Class pClass = People.class;
            //2. Get the method information in the class
            //Gets a method without parameters
            Method aaa = pClass.getMethod("aaa");
            System.out.println(aaa);
    
            //invoke(Object obj, Object... args) calls this method through the invoKe method
            aaa.invoke(pClass.newInstance());//Call aaa() method
    
            //Get methods with parameters
            Method aaa1 = pClass.getMethod("aaa", int.class);
            System.out.println(aaa1);
            aaa1.invoke(pClass.newInstance(),6);
            /*
            The access method of permission modifier is not considered
             */
            //Get a single, according to the method name and parameter type
            Method bbb = pClass.getDeclaredMethod("bbb", int.class);
            System.out.println(bbb);
    
            //Get all
            Method[] methods = pClass.getDeclaredMethods();
            System.out.println(Arrays.toString(methods));
        }
    
  • Get annotation information

    /**
         * Get annotation information
         */
        @Test
        public void test4() throws  Exception{
            //1. Get bytecode object of class
            Class<People> pClass = People.class;
            //2. Get the information of annotation
            //Get annotation object
            Annotation annotation1 = pClass.getAnnotation(MyAnno.class);
            System.out.println(annotation1);
    
            //Force the Annotation object of Annotation type into the subclass type we use
            MyAnno myanno = (MyAnno) pClass.getAnnotation(MyAnno.class);
            System.out.println(myanno);
            System.out.println(myanno.value());
        }
    

    Note: if you want to retrieve the value set in the Annotation, you need to forcibly convert the obtained Annotation object into the Annotation object you use

1.2.4 reflection cases

(1) Create a custom annotation (used to get the attribute value of the annotation attribute)
//Specify the scope of use of annotations
@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {
    String value();
}

(2) Create an entity class and add annotations
@TableName("book")
public class Book {
    @FieldName("bookid")
    private Integer id;
    @FieldName("bookname")
    private String bookname;
    @FieldName("typeid")
    private Integer typeid;
    @FieldName("author")
    private String author;
}
(3) Use the reflection mechanism to get the Book object and splice its properties into an aql query statement
public class SelectSql {

    /**
     * Main function
     * */
    public static void main(String[] args) throws Exception{
        //Get the query statement of book
        String sql = getSql(Book.class);
        System.out.println(sql);


    }

    /**
     * Customize a static method to obtain the method of query statement, and pass in the bytecode of the entity class to be obtained
     * */
    public static String getSql(Class c){
        //1. Get bytecode object of entity class
        Class bookClass = c;
        //Class<?> bookClass = Class.forName("com.aaa.reflex.demo2.User");

        //2. Extract annotation information from entity class
            //2.1 extract table name
            TableName tableName =(TableName) bookClass.getAnnotation(TableName.class);
            System.out.println(tableName.value());
            //2.2 extract field name
            Field[] fields = bookClass.getDeclaredFields();
            //System.out.println(Arrays.toString(fields));

            //Create a list to store all field names
            ArrayList<String> strings = new ArrayList<>();
            for (int i = 0; i < fields.length; i++) {
                FieldName fieldName = fields[i].getAnnotation(FieldName.class);
                strings.add(fieldName.value());
            }
            System.out.println(strings);

        //3. Process the extracted table name and field name into the sql statement we need
        StringBuffer sql = new StringBuffer("select ");
        for (int i = 0; i < strings.size(); i++) {
            if(i<strings.size()-1){
                sql.append(strings.get(i)+",");
            }else{
                sql.append(strings.get(i)+" ");
            }
        }
        sql.append("from "+tableName.value());
        //System.out.println(sql);
        return sql.toString();
    }
}
(4) Operation results:

Keywords: Java reflection

Added by russthebarber on Sat, 19 Feb 2022 19:10:54 +0200