annotation
Basic notes:
**JAVA annotation: * * also known as JAVA annotation, is an annotation mechanism introduced by JDK 5.0. Not the program itself, the program can be revealed and can be read by other programs.
Format: @ + comment name (some can also add parameters)
**@Override 😗* rewrite. If it is found that its parent class or the referenced interface does not have this method, a compilation error will be reported.
// @Override override annotation @Override public String toString() { return super.toString(); }
**@Deprecated: * * mark obsolete method. If this method is used, a compilation warning will be reported.
// @Deprecated is not recommended for programmers, but it can be used, or there is a better way @Deprecated public static void test(){ System.out.println("Deprecated"); }
@SuppressWarnings: instructs the compiler to ignore the warnings declared in the comments. Parameters are required.
// @SuppressWarnings suppression warnings @SuppressWarnings("all") public void test02(){ List list = new ArrayList<>(); }
Meta annotation:
Meta annotation: responsible for annotating other annotations
@Target: describes the scope of use of annotations
**@Retention: * * describes the lifecycle of the annotation
**@Documented: * * this annotation will be included in the javadoc
**@Inherited: * * the subclass can inherit the annotation in the parent class
import java.lang.annotation.*; // Test meta annotation public class test02 { @MyAnnotation 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 // If not, the default is class // 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 // To define annotations, @ interface is required @interface MyAnnotation{ }
Custom annotation
Using @ interface to customize annotations automatically inherits Java lang.annotation. Annotation interface
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, annotations must be assigned without order @MyAnnotation2(name = "aa",sc) public void test(){} @MyAnnotation3("") public void test2(){ } } @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2{ // Annotated parameters: parameter type + parameter name (); String name(); // String name() default ""; Add default value, no parameters can be added int age() default 0; int id() default -1; // If the default value is - 1, it means that it does not exist String[] schools() default {"aa","bb"}; } @interface MyAnnotation3{ String value(); // If there is only one value, value is used by default, and assignment is not required }
Annotation components:
In the composition of java Annotation, there are three very important trunk classes. namely:
Annotation.java
package java.lang.annotation; public interface Annotation { boolean equals(Object obj); int hashCode(); String toString(); Class<? extends Annotation> annotationType(); }
ElementType.java
package java.lang.annotation; public enum ElementType { TYPE, /* Class, interface (including annotation type), or enumeration declaration */ FIELD, /* Field declaration (including enumeration constants) */ METHOD, /* Method declaration */ PARAMETER, /* Parameter declaration */ CONSTRUCTOR, /* Construction method declaration */ LOCAL_VARIABLE, /* Local variable declaration */ ANNOTATION_TYPE, /* Annotation type declaration */ PACKAGE /* Package declaration */ }
RetentionPolicy.java
package java.lang.annotation; public enum RetentionPolicy { SOURCE, /* Annotation The information only exists during the compiler processing, and there is no Annotation information after the compiler processing */ CLASS, /* The compiler stores the Annotation in the corresponding of the class Class file. Default behavior */ RUNTIME /* The compiler stores the Annotation in a class file and can be read in by the JVM */ }
Note more detailed description: https://www.runoob.com/w3cnote/java-annotation.html
reflex
Basic definition of class:
**Reflection: * * load the class and get the components of the class
Class:
- 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 dynamically loaded and running class, you should first obtain the corresponding class object
// Get the class object of the class through reflection Class c1 = Class.forName("User"); System.out.println(c1); Class c2 = Class.forName("User"); Class c3 = Class.forName("User"); // A class has only one class object in memory // After a class is loaded, the whole construction of the class will be encapsulated in the class object System.out.println(c2.hashCode()); System.out.println(c3.hashCode());
Get class type instance:
- If a specific class is known, this method is the most reliable and the program performance is the highest through the class attribute of the class
- 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
- If the instance of a Class is known, call the getClass() method of the instance to get the Class object
- The built - in basic data type can use the class name directly Type
- Using Class Loader
// Method 1: obtained by object Class c1 = person.getClass(); System.out.println(c1.hashCode()); // Method 2: forname Class c2 = Class.forName("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(); Syste.out.println(c5);
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, and then generate a Java. Java.xml 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 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) of the virtual machine constant pool with a direct reference (address)
-
-
initialization:
- The process of executing a class constructor () method.
- When initializing a class, if it is found that its parent class has not been initialized, you need to touch the initialization of its parent class first
- Virtual chance ensures that the () methods of a class are locked and synchronized correctly in a multithreaded environment.
// When does the test class initialize public class Test06 { static { System.out.println("Main Class is loaded"); } public static void main(String[] args) { // 1. Active quotation // Son son = new Son(); // Reflection also produces active references try { Class.forName("Son"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class Father{ 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; }
When will 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 is an object of a class
- Call static members (except final constants) and static methods of the class
- 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, initialize its parent class 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
- Defining class references through arrays does not initiate class initialization
- Reference constants do not initialize this class
**Function of class loader: * * load classes into memory. There are boot class loader, extension class loader and system class loader.
public class Test07 { public static void main(String[] args) throws ClassNotFoundException { // Gets the loader of the system class ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); // Get the parent class loader -- > extension class loader of the system class loader ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); // Gets the parent class loader -- > root loader of the extension class loader ClassLoader parent1 = parent.getParent(); System.out.println(parent1); // Test which loader loads the current class ClassLoader classLoader = Class.forName("Test07").getClassLoader(); System.out.println(classLoader); // Test who loaded the JDK built-in classes classLoader = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader); // How to get the path that the system loader can load System.out.println(System.getProperty("java.class.path")); // Parental delegation mechanism // java.lang.String --> } }
Application of reflection:
Get the complete structure of the runtime class:
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test08 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("User"); // User user = new User(); // c1 = user.getClass(); // Get the name of the class System.out.println(c1.getName()); // Get package name + class name System.out.println(c1.getSimpleName()); // Get class name // Get the properties of the class System.out.println("+++++++++++++++++++++++++++++++"); Field[] fields = c1.getFields(); // Only public properties can be found fields = c1.getDeclaredFields(); // Find all properties for(Field field: fields){ System.out.println(field); } Field name = c1.getDeclaredField("name"); System.out.println(name); // Method to get class System.out.println("+++++++++++++++++++++++++++++++++"); Method[] methods = c1.getMethods(); // Get all public methods of this class and its parent class for(Method method: methods){ System.out.println("natural:"+method); } methods = c1.getDeclaredMethods(); // Get all methods of this class for(Method method : methods){ System.out.println("getDeclareMethods:"+method); } // Gets the specified method Method getName = c1.getMethod("getName", null); Method setName = c1.getMethod("setName", String.class); System.out.println(getName); System.out.println(setName); // Gets the specified constructor System.out.println("+++++++++++++++++++++++++++"); Constructor[] constructors = c1.getConstructors(); for(Constructor constructor : constructors){ System.out.println("#"+constructor); } constructors = c1.getDeclaredConstructors(); for(Constructor constructor : constructors){ System.out.println("#" + constructor); } // Gets the specified constructor Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class); System.out.println("appoint:"+declaredConstructor); } }
Performance comparison:
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; // Analyze performance issues public class Test10 { // Normal mode call public static void test01(){ User user = new User(); long startTime = System.currentTimeMillis(); for(int i = 0; i < 1000000000;i++){ user.getName(); } long endTime = System.currentTimeMillis(); System.out.println("1 billion times with common methods:"+(endTime-startTime)+"ms"); } // Reflection mode call public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); long startTime = System.currentTimeMillis(); for(int i = 0; i < 1000000000;i++){ getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("The reflection method is executed 1 billion times:"+(endTime-startTime)+"ms"); } // Reflection mode call off detection public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); getName.setAccessible(true); long startTime = System.currentTimeMillis(); for(int i = 0; i < 1000000000;i++){ getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("Close detection and execute 1 billion times:"+(endTime-startTime)+"ms"); } public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { test01(); test02(); test03(); } }
Get generics:
import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; // Get generics through reflection public class Test11 { public void test01(Map<String, User> map, List<User> list){ System.out.println("test01"); } public Map<String, User> test02(){ System.out.println("test02"); return null; } public static void main(String[] args) throws NoSuchMethodException { Method method = Test11.class.getMethod("test01", Map.class, List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType: genericParameterTypes){ System.out.println("#" + genericParameterType); if(genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for(Type actualTypeArgument : actualTypeArguments){ System.out.println(actualTypeArgument); } } } method = Test11.class.getMethod("test02", null); Type genericReturnType = method.getGenericReturnType(); if(genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for(Type actualTypeArgument : actualTypeArguments){ System.out.println(actualTypeArgument); } } } }
Get annotation information:
import java.lang.annotation.*; import java.lang.reflect.Field; public class Test12 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("Student2"); // Get annotations through reflection Annotation[] annotations = c1.getAnnotations(); for(Annotation annotation : annotations){ System.out.println(annotation); } // Get the value of the annotation Tablekuang tablekuang = (Tablekuang)c1.getAnnotation(Tablekuang.class); String value = tablekuang.value(); System.out.println(value); // Gets the annotation specified by the class Field f = c1.getDeclaredField("name"); Filekuang annotation = f.getAnnotation(Filekuang.class); System.out.println(annotation.columnName()); System.out.println(annotation.type()); System.out.println(annotation.length()); } } @Tablekuang("db_student") class Student2{ @Filekuang(columnName = "db_id", type = "int", length = 10) private int id; @Filekuang(columnName = "db_age", type = "int", length = 10) private int age; @Filekuang(columnName = "db_name", type = "varchar", length = 3) private String name; public Student2(){ } public Student2(int id, int age, String name) { this.id = id; this.age = age; 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; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student2{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + '}'; } } // Annotation of class name @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Tablekuang{ String value(); } // Attribute annotation @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface Filekuang{ String columnName(); String type(); int length(); }
According to the notes made by the Java annotation and reflection of the UP master madness of station B. Video address