Annotation and reflection of Java learning-2021-08-17

Posted by Dawg on Wed, 22 Dec 2021 14:11:15 +0100

Annotation and reflection

annotation

Java.Annotation

Introduction to annotation

What is annotation

  • Annotation is from jdk5 0 began to introduce new technologies
  • Function of Annotation:
    • Not the program itself, you can explain the program (this is no different from comments)
    • It can be read by other programs (such as compiler, etc.)
  • Format of Annotation:
    • Comments exist in the code as @ comment name. You can also add some parameter values, such as @ SuppressWarnings(value = "unchecked")
  • Where is Annotation used?
    • It can be attached to package, class, method, field, etc., which is equivalent to adding auxiliary information to them. We can access these metadata through reflection mechanism programming
package com.wyy.annotation;

//What is annotation
public class Test01 extends Object{

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

Built in annotation

  • @Override: defined in Java In lang. override, this annotation is only applicable to rhetoric, indicating that one method declaration intends to override another method declaration in the superclass

  • @Deprecated: defined in Java In lang. deprecated, this annotation can be used for rhetoric, attributes, and classes to indicate that programmers are not encouraged to use such elements, usually because it is dangerous or there are better choices

  • @SuppressWarnings: defined in Java Lang. SuppressWarnings, used to suppress warnings at compile time

    Different from the previous two comments, you need to add a parameter to use it correctly. These parameters have been defined. We can use them selectively

    @SuppressWarnings("all)

    @SuppressWarnings("unchecked")

    @SuppressWarnings(value={"unchecked","deprecation"})

    Wait

package com.wyy.annotation;

import java.util.ArrayList;
import java.util.List;

//What is annotation

public class Test01 extends Object{

    //@Override overridden annotation
    @Override
    public String toString() {
        return super.toString();
    }
    //@Deprecated is not recommended for programmers, but it can be used. There is a better way to live
    @Deprecated
    public static void test(){
        System.out.println("@Deprecated");
    }
    //@SuppressWarnings suppression warnings
    @SuppressWarnings("all")
    public void test02(){
        List list = new ArrayList();
    }

    public static void main(String[] args) {
        test();
    }
}

Meta annotation

  • The function of no annotation is to annotate other annotations. Java defines four standard meta annotation types, which are used to describe other annotation types
  • These types and the classes they support are in Java * * can be found in lang.annotation package (@ target@ Retention@Documented , @Inherited )**
    • @Target: used to describe the scope of use of annotations (i.e. where the described annotations can be used)
    • @Retention: indicates the level at which the annotation information needs to be saved. It is used to describe the annotation life cycle
      • (SOURCE <CLASS < RUNTIME)
    • **@Document: * * indicates that the annotation will be included in javadoc
    • @Inherited: indicates that the subclass can inherit the annotation in the parent class
package com.wyy.annotation;

import java.lang.annotation.*;

//Test meta annotation
@MyAnnotation
public class Test02 {
    public void test(){
    }
}

//Define an annotation
//@Target indicates where our annotation can be used
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//@Retention indicates where our annotation is still valid
//  runtime>class>sources
@Retention(value = RetentionPolicy.RUNTIME)
//@Documented indicates whether our annotations are generated in JAVAdoc
@Documented
//@The Inherited subclass can inherit the annotation of the parent class
@Inherited
//@interface custom annotation
@interface  MyAnnotation{

}

Custom annotation

  • Custom annotation when using @ intefface custom annotation, it automatically inherits Java lang.annotation. Annotation interface
  • analysis:
    • @Interface is used to declare an annotation. Format: public @ interface annotation name {definition content}
    • Each of these methods actually declares a configuration parameter
    • The name of the method is the name of the parameter
    • The return value type is the type of the parameter (the return value can only be the basic type, class, string, enum)
    • You can declare the default value of the parameter through default
    • If there is only one parameter member, the general parameter name is value
    • An annotation element must have a value. When defining an annotation element, we often use an empty string with 0 as the default value
package com.wyy.annotation;

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

//Custom annotation
public class Test03 {
    //Annotations can display assignments. If there is no default value, we must assign a value to the annotation
    @MyAnnotation2(age = 19, name = "nineteen")
    public void test() {}
    
    //If there is only one value, we suggest to assign value, which can be omitted
    @MyAnnotation3("")
    public void test2() {}

}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
    //Annotated parameters: parameter type + parameter name ()
    String name() default "";

    int age();
    //If the default value is - 1, it means that it does not exist, indexof. If it cannot be found, it returns - 1
    int id() default -1;

    String[] schools() default {"university","vocational school"};
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    //If there is only one value, we suggest to assign value, which can be omitted
    String value();
}

Reflection mechanism

Java.Reflection

Overview of Java reflection mechanism

Static VS dynamic language

  • Dynamic language
    • It is a kind of language that can change its structure at run time: for example, new functions, objects and even code can be introduced, existing functions can be deleted or other structural changes. Generally speaking, the code can change its structure according to some conditions at run time.
    • Main dynamic languages: Object-C, C#, JavaScript, PHP,Python, etc.
  • Static language
    • Corresponding to dynamic language, the language with immutable runtime structure is static language. Such as Java, C.C + +
    • Java is not a dynamic language, but Java can be called a "quasi dynamic language". That is, Java has certain dynamics. We can use reflection mechanism to obtain characteristics similar to dynamic language. The dynamic nature of Java makes programming more flexible!

Java.Reflection

  • Reflection is the key to Java being regarded as a dynamic language. Reflection mechanism allows programs to obtain the internal information of any class with the help of Reflection API during execution, and can directly operate the internal properties and methods of any object.
Class c = Class.forName("java.lang.String")
  • After loading the Class, a Class object is generated in the method area of heap memory (a Class has only one Class object), which contains the complete Class structure information. We can see the structure of the Class through this object. This object is like a mirror, through which we can see the structure of the Class. Therefore, we vividly call it reflection

Research and application of Java reflection mechanism

Functions provided by Java reflection mechanism

  • Determine the class of any object at run time
  • Construct an object of any class at run time
  • Judge the member variables and methods of any class at run time
  • Get generic information at run time
  • Call the member variables and methods of any object at run time
  • Processing annotations at run time
  • Generate dynamic proxy
  • ...

The advantages and disadvantages of Java reflection are as follows:

advantage:

  • It can dynamically create objects and compile, reflecting great flexibility

shortcoming

  • It has an impact on performance. Using reflection is basically an interpretation operation. We can tell the JVM what we want to do and it meets our requirements. Such operations are always slower than performing the same operation directly.

Main API s related to reflection

  • java.lang.Class: represents a class
  • java.lang.reflect.Method: represents the method of the class
  • java.lang.reflect.Field: represents the member variable of the class
  • java.lang.reflect.Constructor: represents the constructor of the class
package com.wyy.reflection;

//What is reflection
public class Test02 extends Object{
    public static void main(String[] args) throws ClassNotFoundException {
        //Get Class object by reflection
        Class c1 = Class.forName("com.wyy.reflection.User");
        System.out.println(c1);
        Class c2 = Class.forName("com.wyy.reflection.User");
        Class c3 = Class.forName("com.wyy.reflection.User");
        Class c4 = Class.forName("com.wyy.reflection.User");
/**
 Hashcod It doesn't mean it's an object
 We have to compare equals. hashcod is only screened in advance and is efficient
 hashcod If it's different, it must be different. If it's the same, it's more rigorous than equals.
 */
        //A Class has only one Class mapping in memory
        //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());

    }

}

//Entity class: pojo,entity
class User {
    private String name;
    private int id;
    private int age;

    public User() {
    }

    public User(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

Understand Class class and get Class instance

Class class

  • The following methods are defined in the Object class, which will be inherited by all subclasses

    public final Class getClass()
    
  • The type of the return value of the above method is a Class class, which is the source of Java reflection. In fact, the so-called reflection is also well understood from the running results of the program, that is, the name of the Class can be obtained through object reflection.

The information that can be obtained after the object looks in the mirror: the attributes, methods and constructors of a Class, and which interfaces a Class implements. For each Class, JRE reserves an object of constant Class type. A Class object contains information about a specific structure (class/interface/enum/annotation/primitive type/void / [).

  • Class itself is also a class
  • Class objects can only be created by the system
  • A loaded Class has only one Class instance in the JVM
  • A class object corresponds to a class loaded into the JVM Class file
  • Each Class instance will remember which Class instance it was generated from
  • All loaded structures in a Class can be completely obtained through Class
  • Class is the root of Reflection. For any class you want to dynamically load and run, you have to obtain the corresponding class object first
Method nameFunction description
static ClassforName(String name)Returns the Class object with the specified Class name
Object newlnstance()Call the default constructor to return an instance of the Class object
getName()Returns the name of the entity (Class, interface, array Class or void) represented by this Class object.
Class getSuperClass()Returns the Class object of the parent Class of the current Class object
Class[] getinterfaces()Gets the interface of the current Class object
ClassLoader getClassLoader()Returns the class loader for this class
Constructor[] getConstructors()Returns an array containing some Constructor objects
Method getMothed(String name,Class... T)Returns a Method object whose formal parameter type is paramType
Field[] getDeclaredFields()Returns an array of Field objects

Get an instance of Class

a) if a specific class is known, it is obtained through the class attribute of the class. This method is the most safe and reliable and has the highest program performance.

Class clazz = Person.class;

b) if the instance of a Class is known, call the getClass() method of the instance to obtain the Class object

Class clazz = person.getClass();

c) if the full Class name of a Class is known and the Class is under the Class path, it can be obtained through the static method forName() of Class class, and ClassNotFoundException may be thrown

Class clazz = Class.forName("demo01.Student");

d) the built-in basic data type can directly use the class name Type

e) you can also use ClassLoader

package com.wyy.reflection;

//What are the creation methods of test Class
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException {
        //A parent class reference points to a child class object
        Person person = new Student();
        System.out.println("This man is:" + person.name);

        //Methods are: obtained by object
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());

        //Method 2: forname
        Class c2 = Class.forName("com.wyy.reflection.Student");
        System.out.println(c2.hashCode());

        //Method 3: pass the class name Class get
        Class c3 = Student.class;
        System.out.println(c3.hashCode());

        //Method 4: wrapper classes of basic built-in types have a Type attribute
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        //Get parent type
        Class c5 = c1.getSuperclass();
        System.out.println(c5);

    }

}

class Person {
    String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Student extends Person {
    public Student() {
        this.name = "student";
    }
}

class Teacher extends Person {
    public Teacher() {
        this.name = "teacher";
    }
}

What types can have Class objects?

  • Class: external class, member (member internal class, static internal class), local internal class, anonymous internal class.
  • interface: interface
  • []: array
  • Enum: enum
  • Annotation: annotation @ interface
  • primitive type: basic data type
  • void
package com.wyy.reflection;

import java.lang.annotation.ElementType;

//Class of all types
public class Test04 {
    public static void main(String[] args) {
        //Class type
        Class c1 = Object.class;
        //Interface type
        Class c2 = Comparable.class;
        //String type one-dimensional array
        Class c3 = String[].class;
        //int type 2D array
        Class c4 = int[][].class;
        //annotation type 
        Class c5 = Override.class;
        //menu enumeration type
        Class c6 = ElementType.class;
        //Integer basic data type
        Class c7 = Integer.class;
        //void type
        Class c8 = void.class;
        //Class type
        Class c9 = Class.class;

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        //As long as the element type is the same as the dimension, it is the same class
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());


    }
}

Java Memory Analysis

Understanding: class loading process
  			When a program actively uses a class,If the class has not been loaded into memory,The system initializes this class through the following three steps.

Class loading and ClassLoader

  • Load: load the bytecode content of the class file into memory, convert these static data into the runtime data structure of the method area, and then generate a Java. Net file representing this class Lang.class object
  • Link: the process of merging the binary code of Java classes into the running state of the JVM.
    • Verification: ensure that the loaded class information complies with the JVM specification and there are no security problems
    • Preparation: the stage of formally allocating memory for class variables (static) and setting the default initial value of class variables. These memory will be allocated in the method area.
    • Resolution: the process of replacing the symbolic reference (constant name) in the virtual machine constant pool with a direct reference (address).
  • initialization:
    • The process of executing a class constructor () method. The class constructor () method is generated by automatically collecting the assignment actions of all class variables in the class at compile time and combining the statements in the static code block. (the class constructor is used to construct class information, not the constructor to construct the class object.).
    • When initializing a class, if it is found that its parent class has not been initialized, the initialization of its parent class needs to be triggered first
    • Virtual chance ensures that the () methods of a class are locked and synchronized correctly in a multithreaded environment.
package com.wyy.reflection;

public class Test05 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
        /*
            1.When loaded into memory, a Class object corresponding to the Class will be generated
            2.Chain press, m =.
            3.initialization
            <clinit>(){
                    System. out.printIn("A Class static code block initialization "");
                    m = 300;
                    m = 100;
            }
            m=100
         */
    }
}

class A {
    static {
        System.out.println("A Class static code block initialization");
        m = 300;
    }
    /*
    m=300
    m=100
     */

    static int m = 100;

    public A() {
        System.out.println("A Class");
    }
}

When does class initialization occur?

  • Active reference of class (class initialization must occur)
    • When the virtual machine starts, initialize the class where the main method is located first
    • new the object of a class calls the static members of the class (except the final constant) and static methods using Java The method of lang.reflect package makes reflection calls to the class
    • When initializing a class, if its parent class is not initialized, its parent class will be initialized first
  • Passive reference of class (class initialization will not occur)
    • When accessing a static domain, only the class that actually declares the domain will be initialized. For example, when a static variable of a parent class is referenced through a subclass, the subclass will not be initialized
    • Defining a class reference through an array does not trigger the initialization of this class
    • Reference constants do not trigger the initialization of this class (constants are stored in the constant pool of the calling class in the link phase)
package com.wyy.reflection;

//When will the test class initialize
public class Test06 {
  static {
      System.out.println("main Method is loaded");
  }

    public static void main(String[] args) throws ClassNotFoundException {
        //1. Active reference
        //Son son = new Son();

        //Reflection also produces active references
        //Class.forName("com.wyy.reflection.Son");

//===========================================================
        //A method that does not generate a reference to a class
        //System.out.println(Son.b);

        //Son[] array = new Son[5];// Nothing will be loaded except the main method

        System.out.println(Son.M);

    }


}

class Father {
    static int b = 2;
    static {
        System.out.println("The parent class is loaded");
    }
}

class Son extends Father {
    static {
        System.out.println("Subclass loaded");
        m = 300;
    }

    static int m = 100;
    static final int M = 1;
}

Unfinished to learn~

Create an object for the runtime class

Gets the complete structure of the runtime class

Calls the specified structure of the runtime class

Topics: Java