Notes + reflection notes

Reflection: the soul of frame design

The first thing to write is *. java The file is generated by the compiler *.class Finally, the bytecode is run through the virtual machine *.class file

* Framework: semi-finished software. Software development can be carried out on the basis of the framework to simplify coding
* Reflection: encapsulating the components of a class into other objects is the reflection mechanism
	* Benefits:
		1. These objects can be run during these operations.
		2. It can decouple and improve the scalability of the program

[the external chain image transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-Vpffvv22-1620301243675)(D:\java learning video \ javaWeb \ course materials \ day01_ foundation strengthening \ notes \ three stages of Java code. bmp)]

Classloader: loads bytecode files (*. class) into memory

class is used to describe the common characteristics and behavior of all bytecode files

  • How to get Class object:
	1. Class.forName("Full class name"): Load bytecode file into memory and return Class object  //Source code phase
		* It is mostly used for configuration files, and the class name is defined in the configuration file. Read files and load classes
	2. Class name.class: Attribute by class name class obtain	//Class object stage
		* It is used to transfer parameters
	3. object.getClass(): getClass()Method in Object Class.	//Runtime phase
		* It is mostly used for obtaining bytecode of objects

example:

package cn.itcast.domain;

public class Person {
    private String name;
    private int age;

    public String a;
    protected String b;
    String c;
    private String d;


    public Person() {
    }

    public Person(String name, int age) {

        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }
    public void eat(){
        System.out.println("eat...");
    }

    public void eat(String food){
        System.out.println("eat..."+food);
    }
}
package cn.itcast.domain;

public class Student {
    public void sleep(){
        System.out.println("sleep...");
    }
}
import cn.itcast.domain.Person;
import cn.itcast.domain.Student;

public class ReflectDemo1 {
    /**
        How to get Class object:
            1. Class.forName("Full Class name "): load bytecode file into memory and return Class object
            2. Class name Class: obtained through the attribute class of the class name
            3. Object getClass(): the getClass() method is defined in the object class.
     */
    public static void main(String[] args) throws Exception {

        //1.Class.forName("full class name")
        Class cls1 = Class.forName("cn.itcast.domain.Person");
        System.out.println(cls1);
        //2. Class name class
        Class cls2 = Person.class;
        System.out.println(cls2);
        //3. Object getClass()
        Person p = new Person();
        Class cls3 = p.getClass();
        System.out.println(cls3);

        //==Compare three objects
        System.out.println(cls1 == cls2);//true
        System.out.println(cls1 == cls3);//true
		//
        Class c = Student.class;
        System.out.println(c == cls1);//false


    }
}
  • Class object function: (must remember)
* Get function:
	1. Get member variables
		* Field[] getFields() : Get all public Decorated member variable
		* Field getField(String name)   Gets the of the specified name public Decorated member variable

		* Field[] getDeclaredFields()  Get all member variables, regardless of modifiers
		* Field getDeclaredField(String name)  
	2. Get constructors
		* Constructor<?>[] getConstructors()  
		* Constructor<T> getConstructor(class<?>... parameterTypes)  

		* Constructor<T> getDeclaredConstructor(class<?>... parameterTypes)  
		* Constructor<?>[] getDeclaredConstructors()  
	3. How to get members:
    //Note: the getMethods() method obtains the method of adding its own parent class!!!!
    //     getDeclaredMethods() only gets its own method!!!
    // There is no question of distinguishing between modifiers
		* Method[] getMethods()  
		* Method getMethod(String name, class<?>... parameterTypes)  

		* Method[] getDeclaredMethods()  
		* Method getDeclaredMethod(String name, class<?>... parameterTypes)  

	4. Get full class name	
		* String getName()  

(1) Field part:

* Field: Member variable
	* Operation:
		1. Set value
			* void set(Object obj, Object value)  
		2. Get value
			* get(Object obj) 

		3. Ignore security checks for access modifier
			* setAccessible(true):Violent reflex

(1) Code of field method:

package cn.itcast.reflect;

import cn.itcast.domain.Person;
import java.lang.reflect.Field;

public class ReflectDemo2 {
    public static void main(String[] args) throws Exception {

        //0. Get the Class object of Person
        Class personClass = Person.class;
        /*
             1. Get member variables
                 * Field[] getFields()
                 * Field getField(String name)

                 * Field[] getDeclaredFields()
                 * Field getDeclaredField(String name)

         */
        //1.Field[] getFields() gets the member variables of all public modifiers
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("------------");
        //2.Field getField(String name)
        Field a = personClass.getField("a");
        //Gets the value of the member variable a
        Person p = new Person();
        Object value = a.get(p);
        System.out.println(value);
        //Set the value of a
        a.set(p,"Zhang San");
        System.out.println(p);

        System.out.println("===================");

        //Field [] getdeclaraedfields(): get all member variables, regardless of modifiers
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //Field getDeclaredField(String name)
        Field d = personClass.getDeclaredField("d");
        //Ignore the security check of the access modifier in order to access the value of private member variables
        d.setAccessible(true);//Violent reflex
        Object value2 = d.get(p);
        System.out.println(value2);

    }
}

(2) Constructor part:

* Constructor:Construction method
	* Create object:
		* T newInstance(Object... initargs)  //Variable parameter

		* If you use the null parameter construction method to create objects, the operation can be simplified: Class Object newInstance method

(2) Constructor code:

package cn.itcast.reflect;

import cn.itcast.domain.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class ReflectDemo3 {
    public static void main(String[] args) throws Exception {

        //0. Get the Class object of Person
        Class personClass = Person.class;
        /*
            2. Get constructors
                 * Constructor<?>[] getConstructors()
                 * Constructor<T> getConstructor(Class <? > parameterTypes)

                 * Constructor<T> getDeclaredConstructor(Class <? > parameterTypes)
                 * Constructor<?>[] getDeclaredConstructors()
         */

		//Here is only one method:
        //Constructor < T > getconstructor (class <? >... Parametertypes)
        //Note: parameters are bytecode objects
        Constructor constructor = personClass.getConstructor(String.class, int.class);
        System.out.println(constructor);
        //create object
        Object person = constructor.newInstance("Zhang San", 23);
        System.out.println(person);

        System.out.println("----------");

		//(1) Getting an object without parameters is the same as the following method
        Constructor constructor1 = personClass.getConstructor();
        System.out.println(constructor1);
        //create object
        Object person1 = constructor1.newInstance();
        System.out.println(person1);
        
		//(2) This should be simpler
        Object o = personClass.newInstance();
        System.out.println(o);


        //constructor1.setAccessible(true);  // Same as above
    }
}

(3) Method:

* Method: Method object
	* Execution method:
		* Object invoke(Object obj, Object... args)  

	* Get method name:
		* String getName:Get method name

(3) Method code part:

package cn.itcast.reflect;

import cn.itcast.domain.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectDemo4 {
    public static void main(String[] args) throws Exception {

        //0. Get the Class object of Person
        Class personClass = Person.class;
        /*
          3. How to get members:
             * Method[] getMethods()
             * Method getMethod(String name, Class <? > parameterTypes)

             * Method[] getDeclaredMethods()
             * Method getDeclaredMethod(String name, Class <? > parameterTypes)
         */
        //Gets the method of the specified name
        Method eat_method = personClass.getMethod("eat");
        Person p = new Person();
        //Execution method
        eat_method.invoke(p);


        Method eat_method2 = personClass.getMethod("eat", String.class);
        //Execution method
        eat_method2.invoke(p,"meal");

        System.out.println("-----------------");

        //Get the methods of all public modifiers
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            String name = method.getName();
            System.out.println(name);
            //method.setAccessible(true);
        }

        //Get class name
        String className = personClass.getName();
        System.out.println(className);//cn.itcast.domain.Person

    }
}

Case: (there is something you don't understand) classLoad

  • Case:
    • Requirements: write a "framework", which can help us create objects of any class and execute any method under the premise of not changing any code of this class
      • realization:
        1. configuration file
        2. reflex
      • Steps:
        1. Define the full class name of the object to be created and the method to be executed in the configuration file
        2. Load read configuration file in program
        3. Use reflection technology to load class files into memory
        4. create object
        5. Execution method
//configuration file
//File name: pro properties
className=cn.itcast.domain.Student
methodName=sleep

It can help us create objects of any class and execute any of its methods:

package cn.itcast.reflect;

import cn.itcast.domain.Person;
import cn.itcast.domain.Student;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
/**
 * Framework class
 */
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //You can create objects of any class and execute any method
        /*
            Premise: no code of this class can be changed. You can create objects of any class and execute any method
         */
      /*  Person p = new Person();
        p.eat();*/
/*
        Student stu = new Student();
        stu.sleep();*/

        //1. Load configuration file
        //1.1 create Properties object
        Properties pro = new Properties();
        //1.2 load the configuration file and convert it into a collection
        //1.2.1 get the configuration file under the class directory (don't understand!!!)
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        pro.load(is);

        //2. Get the data defined in the configuration file
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");


        //3. Load this class into memory
        Class cls = Class.forName(className);
        //4. Create object
        Object obj = cls.newInstance();
        //5. Get method object
        Method method = cls.getMethod(methodName);
        //6. Implementation method
        method.invoke(obj);
    }
}

Notes:

  • Concept: describe the of the program. For the computer
  • Note: use text to describe the of the program. For programmers

Baidu Encyclopedia:

  • Definition: Annotation, also known as metadata. A code level description. It is jdk1 A feature introduced in version 5 and later is at the same level as class, interface and enumeration. It can be declared in front of packages, classes, fields, methods, local variables, method parameters, etc. to describe and annotate these elements.
  • Concept description:
    • JDK1. New features after 5
    • Description of the procedure
    • Use annotation: @ annotation name

Annotation function classification: (important)

* Function classification:
	①Write document: generate document through the annotation identified in the code [generate document] doc [document]
	②Code analysis: analyze the code through the annotation marked in the code [use reflection] //Main learning!!!
	③Compilation check: the compiler can realize basic compilation check through the annotations identified in the code[ Override]

1. Explanation: document preparation:

//In the figure below, annodemo1 packge is not written in Java
/**
 * Annotation javadoc demo
 *
 * @author itcat
 * @version 1.0
 * @since 1.5
 */
public class AnnoDemo1 {

    /**
     * Calculate the sum of two numbers
     * @param a integer
     * @param b integer
     * @return Sum of two numbers
     */
    public int add(int a, int b ){
        return a + b;
    }
}

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-7ud7gx2w-1620301243683) (C: \ users \ 17274 \ appdata \ roaming \ typora user images \ image-20200817204834039. PNG)]

then:

Click to open:

After:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-cqiflilw-1620301243686) (C: \ users \ 17274 \ appdata \ roaming \ typora \ typora user images \ image-20200817205141516. PNG)]

3. Explanation: compilation check

=========================================================================

Some predefined annotations in JDK:

  • @Override: check whether the method marked by the annotation inherits from the parent class (Interface)
  • @Deprecated: the content marked by this annotation indicates that it is outdated
  • @SuppressWarnings: suppress warnings
    • General transfer parameter all @SuppressWarnings("all")
package cn.itcast.annotation;

import java.util.Date;
/**
 * JDK Some predefined annotations in
 * 		* @Override	: Detect whether the method marked by the annotation inherits from the parent class (Interface)
 * 		* @Deprecated: The content marked in this annotation indicates that it is outdated
 * 		* @SuppressWarnings: Suppress warning
 */
@SuppressWarnings("all")
public class AnnoDemo2 {

    @Override
    public String toString() {
        return super.toString();
    }

    @Deprecated
    public void show1(){
        //Defective
    }

    public void show2(){
        //Alternative show1 method
    }

    public void demo(){
        show1();
        Date date = new Date();//There are many outdated methods in it
    }
}

Custom annotation

* format:

Meta annotation
public @interface Annotation name{
	Attribute list;
}

* essence: Annotation is essentially an interface, which inherits the Annotation interface by default

//MyAnno is a custom annotation name
public interface MyAnno extends java.lang.annotation.Annotation {}

example:

//Annotation is essentially an interface. What can be defined in the interface and what can be defined in the annotation!!!
public @interface MyAnno2 {
	(public abstract) String show();
}

* attribute: abstract method in the interface / / the interface can be any type, and the annotation can only be the following data types!!!

* requirements:

​ 1. The return value type of the property has the following values: no void

* basic data type

​ * String

* enumeration

* notes

* arrays of the above types (annotation array, String array, enumeration array, basic data type array)

Example code:

package cn.itcast.annotation;
//enumeration
public enum Person {
    P1,P2;
}
//annotation
public @interface MyAnno2 {
}
public @interface MyAnno {
	String str();		//String
     int value();		//Basic data type
    Person per();		//enumeration
    MyAnno2 anno2();	//annotation
    String[] strs();
}

​ 2. The attribute is defined, and it needs to be assigned a value when it is used

* if you use the default keyword to initialize the default value of the attribute when defining the attribute, you can not assign the attribute when using annotation.

public @interface MyAnno01{
	int value();
	String str() default "haha";
}

* if only one attribute needs to be assigned and the name of the attribute is value, value can be omitted and the value can be defined directly.

@MyAnno01(5)
public class word{
}
//Question: @ webServlet is how to omit?

* when the array is assigned, the value is wrapped with {}. If there is only one value in the array, {} can be omitted

@MyAnno(value=12,per = Person.P1,anno2 = @MyAnno2,strs="bbb")
public class Worker {
}
//Attribute assignment method:
@MyAnno(value=12,per = Person.P1,anno2 = @MyAnno2,strs={"bbb","aaa"})
public class Worker {
}

* meta annotation: the annotation used to describe the annotation

​ 1. @Target: describes where the annotation can work

ElementType Value:
* TYPE: Can act on classes
* METHOD: Can act on Methods
* FIELD: Can act on member variables

​ 2. @Retention: describes the stage in which annotations are retained

* @Retention(RetentionPolicy.RUNTIME): The annotation currently described will be retained until class Bytecode file, and JVM Read
//Runtime class source three stages!!

​ 3. @Documented: describes whether annotations are extracted into api documents (in the edit document section)

//This meta annotation is added to the a annotation, which annotates the b method. The class of the b method generates an api document, and the a annotation will be displayed on the b method!!  
//If this meta annotation is not added to the a annotation, the a annotation will not be displayed on the b method!!  

​ 4. @Inherited: describes whether annotations are inherited by subclasses

//The subclass here refers to the b annotation annotated by the meta annotation. The b annotation is in class c, and the subclass of class c will also inherit the b annotation!!
//Note: MyAnno3
import java.lang.annotation.*;
/**
 Meta annotation: an annotation used to describe an annotation
     * @Target: Describe where annotations can work
     * @Retention: Describes the stage in which annotations are retained
     * @Documented: Describes whether annotations are extracted into api documents
     * @Inherited: Describes whether annotations are inherited by subclasses
 *
 */
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnno3 {
}
//Class: Worker
@MyAnno(value=12,per = Person.P1,anno2 = @MyAnno2,strs="bbb")
@MyAnno3
public class Worker {
    @MyAnno3
    public String name = "aaa";
    @MyAnno3
    public void show(){
    }
}
//The Teacher class inherits the worker class
public class Teacher extends  Worker {
}

=========================================================================

Use (and parse) annotations in the program: get the attribute values defined in the annotations

​ 1. Get the object of the location defined by the annotation (Class, Method,Field)

​ 2. Gets the specified annotation

​ * getAnnotation(Class)

		//In fact, a subclass implementation object of the annotation interface is generated in memory
	            public class ProImpl implements Pro{
	                public String className(){
	                    return "cn.itcast.annotation.Demo1";
	                }
	                public String methodName(){
	                    return "show";
	                }
	            }

​ 3. Call the abstract method in the annotation to obtain the configured property value

example:

//Annotation pro
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Class name and method name required for execution
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
    String className();
    String methodName();
}
package cn.itcast.annotation;
public class Demo1 {
    public void show(){
        System.out.println("demo1...show...");
    }
}
package cn.itcast.annotation;
public class Demo2 {
    public void show(){
        System.out.println("demo2...show...");
    }
}
package cn.itcast.annotation;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * Framework class
 */


@Pro(className = "cn.itcast.annotation.Demo1",methodName = "show")
public class ReflectTest {
    public static void main(String[] args) throws Exception {

        /*
            Premise: no code of this class can be changed. You can create objects of any class and execute any method
         */


        //1. Analytical notes
        //1.1 get the bytecode file object of this class
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        //2. Get the annotation object above
        //In fact, a subclass implementation object of the annotation interface is generated in memory
        /*

            public class ProImpl implements Pro{
                public String className(){
                    return "cn.itcast.annotation.Demo1";
                }
                public String methodName(){
                    return "show";
                }

            }
 */

        Pro an = reflectTestClass.getAnnotation(Pro.class);
        //3. Call the abstract method defined in the annotation object to obtain the return value
        String className = an.className();
        String methodName = an.methodName();
        System.out.println(className);
        System.out.println(methodName);

        //3. Load this class into memory
        Class cls = Class.forName(className);
        //4. Create object
        Object obj = cls.newInstance();
        //5. Get method object
        Method method = cls.getMethod(methodName);
        //6. Implementation method
        method.invoke(obj);
    }
}

Case: using annotation, the erasure method will return: the exception occurred, the reason, and the number! (some methods are not understood, and the flow is not clear)

  • Class to be checked and wiped!!
//Class to be checked and wiped!!
package cn.itcast.annotation.demo;
/**
 * Calculator class defined by Xiao Ming
 */
public class Calculator {
    //addition
    @Check
    public void add(){
        String str = null;
        str.toString();//Null pointer exception
        System.out.println("1 + 0 =" + (1 + 0));
    }
    //subtraction
    @Check
    public void sub(){
        System.out.println("1 - 0 =" + (1 - 0));
    }
    //multiplication
    @Check
    public void mul(){
        System.out.println("1 * 0 =" + (1 * 0));
    }
    //division
    @Check
    public void div(){
        System.out.println("1 / 0 =" + (1 / 0));
    }

    public void show(){
        System.out.println("Never bug...");
    }

}

Implemented Code:

//annotation
package cn.itcast.annotation.demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check {
}
package cn.itcast.annotation.demo;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Simple test framework
 *
 * When the main method is executed, it will automatically detect all methods (Methods annotated with Check), judge whether there are exceptions in the method, and record them in the file
 */
public class TestCheck {


    public static void main(String[] args) throws IOException {
        //1. Create calculator object
        Calculator c = new Calculator();
        //2. Get bytecode file object
        Class cls = c.getClass();
        //3. Get all methods
        Method[] methods = cls.getMethods();

        int number = 0;//Number of exceptions
        BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));


        for (Method method : methods) {
            //4. Judge whether there is Check annotation on the method
            if(method.isAnnotationPresent(Check.class)){
                //5. Yes, implementation
                try {
                    method.invoke(c);
                } catch (Exception e) {
                    //6. Catch exceptions

                    //Record to file
                    number ++;

                    bw.write(method.getName()+ " The method is abnormal");
                    bw.newLine();
                    bw.write("Name of exception:" + e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("Cause of abnormality:"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write("--------------------------");
                    bw.newLine();

                }
            }
        }

        bw.write("A total of "+number+" Secondary anomaly");

        bw.flush();
        bw.close();
    }
}
--------------------------------------------------------------------------------------

e.getCause().getClass().getSimpleName()
e.getCause().getMessage()I don't know
    
result:    
e.getCause() //java.lang.ArithmeticException: / by zero package name + class name + exception reason
e.getCause().getMessage() //   /by zero exception reason
    

String getSimpleName() 
          Returns the abbreviation of the underlying class given in the source code. 
    
e.getCause().getClass().getName()  //	java.lang.ArithmeticException    
e.getCause().getClass().getSimpleName() //  ArithmeticException    
    
    
    
    

Generate a bug Txt file:

div An exception occurred in the method
 Name of exception: ArithmeticException
 Cause of abnormality:/by zero 
-----------------------------------
One exception occurred in this test
  • Case: simple test framework
  • Summary:
    1. Most of the time in the future, we will use annotations instead of custom annotations
    2. For whom?
      1. compiler
      2. For parser
    3. Annotation is not a part of the program. It can be understood that annotation is a label

Keywords: Java reflection

Added by coolboarderguy on Fri, 18 Feb 2022 02:10:18 +0200