1, Annotation
1. Introduction
- JDK1.5. The new technology introduced is not the program itself, but can explain the program (no difference from annotation)
- Annotations can be read by other programs (such as compiler) (this is the biggest difference from annotations, which can be used as the processing flow of information processing)
2. 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 registration can be used for rhetorical devices, attributes and classes, which means that members are not encouraged to use such elements, usually because it is dangerous or there are better choices, but it can still be used, but it is not recommended
@SuppressWarnings
- Defined in Java Lang. suppresswarnings, used to suppress warnings at compile time
parameter | explain |
---|---|
deprecation | Warning that an obsolete class or method was used |
unchecked | Warning when an unchecked transformation is performed, such as using a collection without specifying a generic type |
fallthrough | case penetration occurs when a switch statement is |
path | There is a warning that the path does not exist in the classpath, source file path, etc |
serial | Warning when a serialVersionUID definition is missing on a serializable class |
finally | Warning when any finally clause cannot be completed |
all | Warning about all of the above |
In fact, the @ SuppressWarnings annotation is rarely used. Most people prefer to use the all parameter
2, Custom annotation
1. Use @ interface to customize annotations
Using its annotations automatically inherits Java lang.annotation. Annotation interface
2. Key points
2.1.@interface is used to declare an annotation
- Format: public @interface annotation name (definition body)
2.2. Each method in its interface 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 type can only be 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
2.3. be careful
- Annotation element must have value! When we define annotation elements, we often use empty string and 0 as the default value
- Negative numbers (such as: - 1) are often used to indicate the meaning of nonexistence
3. Meta annotation
3.1 introduction
- Meta annotations are used to annotate other annotations
- Java defines four standard meta annotation types, which are used to provide descriptions of other annotation types
3.2 type
These types and the classes they support are in Java You can find the following in the lang.annotation package:
- @Target
Function: used to describe the scope of application of the annotation (i.e. where the described annotation can be used)
Modified range | Value ElementType |
---|---|
Package package | PACKAGE |
Class, interface, enumeration, Annotation type | TYPE |
Type member (method, constructor, member variable, enumeration value) | CONSTRUCTOR: user description CONSTRUCTOR FIELD: used to describe the FIELD METHOD: used to describe the METHOD |
Method parameters and local variables | LOCAL, VARIABLE:: used to describe LOCAL variables METHOD: used to describe parameters |
package java.lang.annotation; @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { /** * Returns an array of the kinds of elements an annotation type * can be applied to. * @return an array of the kinds of elements an annotation type * can be applied to */ ElementType[] value(); }
- @Retention
Value RetentionPolicy | effect |
---|---|
SOURCE | Valid in source file (i.e. source file retention) When Java files are compiled into class files, annotations are discarded |
CLASS | Valid in class file (i.e. class reserved) But the jvm was abandoned when it loaded the class file |
RUNTIME | Valid at run time (i.e. reserved at run time) The annotations are not only saved in the class file, but also exist after the jvm loads the class file The Runtime can be read by the reflection mechanism |
These three life cycles correspond to: java source file (. java file) - > Class file - > bytecode in memory
First of all, the life cycle length SOURCE < CLASS < RUNTIME must be clear, so where the former can work, the latter must also work. Generally, if you need to dynamically obtain annotation information at RUNTIME, you can only use RUNTIME annotation; If you want to perform some preprocessing operations during compilation, such as generating some auxiliary code (such as ButterKnife), use the CLASS annotation; if you only do some checking operations, such as @ Override and @ SuppressWarnings, you can use the SOURCE annotation.
package java.lang.annotation; @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }
- @Document
- @Inherited
3.3 realization
Annotation class:
package cn.edu.chan.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Author Cicada * @Date 2021/8/7 12:38 */ @Target(value={ElementType.METHOD,ElementType.TYPE}) //It can be annotated on methods and classes @Retention(RetentionPolicy.RUNTIME) public @interface AnnotationTest01 { String str() default ""; //If the initial value is not defined, the defined annotation needs to pass in the corresponding value, otherwise an error will be reported int integer1() default 0; int integer2() default -1; //-1 means that this value does not exist }
Implementation test class:
package cn.edu.chan.test; /** * @Author Cicada * @Date 2021/8/7 13:10 */ //@AnnotationTest01 public class Test01 { @AnnotationTest01(str = "11",integer1 = 0,integer2 = 1) public void test01(){ } }
3, Reflection read annotation
1. What is ORM (Object Relationship Mapping)
Abbreviation: Object Relational Mapping
For example:
- Class corresponds to table structure
- Attribute and field correspondence
- Object and record correspondence
2. Use annotations to complete the mapping relationship between class and table structure
Annotation class of class:
package cn.edu.chan.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Cicada * @version 1.0 * @date 2021/8/8 10:08 */ @Target(value={ElementType.TYPE}) //Can annotate to class @Retention(RetentionPolicy.RUNTIME) public @interface AnnotationTest02 { String value(); }
Attribute annotation class:
package cn.edu.chan.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Cicada * @version 1.0 * @date 2021/8/8 10:13 */ @Target(value={ElementType.FIELD}) //Can be annotated to attributes @Retention(RetentionPolicy.RUNTIME) public @interface AnnotationTest03 { String columName(); String type(); int length(); }
Entity:
package cn.edu.chan.annotation; /** * @author Cicada * @version 1.0 * @date 2021/8/8 10:08 */ @AnnotationTest02("user") public class User { @AnnotationTest03(columName = "name", type = "varchar", length = 10) private String username; @AnnotationTest03(columName = "psw", type = "varchar", length = 15) private String password; @AnnotationTest03(columName = "age", type = "int", length = 3) private int age; public User() { } public User(String username, String password, int age) { this.username = username; this.password = password; this.age = age; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", age='" + age + '\'' + '}'; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Reflection test class:
package cn.edu.chan.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** *Use reflection to read annotation information and simulate the process of processing annotation information * @author Cicada * @version 1.0 * @date 2021/8/8 10:08 */ public class Test02 { public static void main(String[] args) throws ClassNotFoundException { Class clazz = Class.forName("cn.edu.chan.annotation.User"); //Get all annotations of the class Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //Gets the specified annotation of the class AnnotationTest02 annotation = (AnnotationTest02)clazz.getAnnotation(AnnotationTest02.class); System.out.println(annotation.value()); //Get the annotation of the properties of the class Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { AnnotationTest03 annotationTest03 = field.getAnnotation(AnnotationTest03.class); System.out.println(annotationTest03.columName()+"___"+ annotationTest03.type()+"___"+annotationTest03.length()); } //Annotation reflection obtains information such as table name, spell out SQL statements, and then execute relevant SQL to generate corresponding entity class tables in the database } }
4, Reflection mechanism
1. General
Java reflection mechanism is to know all the properties and methods of any class in the running state; For any object, you can call any of its methods and properties; This kind of dynamically acquired information and the function of dynamically calling object methods are called the reflection mechanism of Java language.
- To dissect a Class, you must first obtain the bytecode file object of the Class, and the dissection uses the methods in the Class Therefore, first get the Class object corresponding to each bytecode file.
- Objects represent or encapsulate some data.
- After a Class is loaded, the JVM will create a Class object corresponding to the Class, and the whole structure information of the Class will be put into the corresponding Class object.
- This Class object is like a mirror, through which I can see all the information of the corresponding Class.
2. Acquisition of class object
Class object acquisition is not so big. Some of the main acquisition methods are those commonly used. Remember, such as class Methods such as forname (fully qualified class name) are sufficient
package cn.edu.chan.myclass; /** * @author Cicada * @version 1.0 * @date 2021/8/8 11:13 */ public class Test01 { public static void main(String[] args) { String path = "cn.edu.chan.annotation.User"; try { Class clazz = Class.forName(path); //Objects represent or encapsulate some data After a Class is loaded, the JVM will create a Class object corresponding to the Class // The entire structure information of the Class will be placed in the corresponding Class object. //This Class object is like a mirror, through which I can see all the information of the corresponding Class. System.out.println(clazz.hashCode()); Class clazz2 = Class.forName(path); //A Class corresponds to only one Class object System.out.println(clazz2.hashCode()); Class strClazz = String.class; Class strClazz2 = path.getClass(); System.out.println(strClazz==strClazz2); Class intClazz =int.class; int[] arr01 = new int[10]; int[][] arr02 = new int[30][3]; int[] arr03 = new int[30]; double[] arr04 = new double[10]; System.out.println(arr01.getClass().hashCode()); System.out.println(arr02.getClass().hashCode()); System.out.println(arr03.getClass().hashCode()); System.out.println(arr04.getClass().hashCode()); } catch (Exception e) { e.printStackTrace(); } } }
result:
1163157884 1163157884 true 1956725890 356573597 1956725890 1735600054 Process finished with exit code 0
It is also clear that a Class corresponds to only one Clss object, but the Class objects corresponding to different dimensions are different.
3. Apply the reflection API to obtain class information (class name, attribute, method, constructor, etc.)
package cn.edu.chan.myConstructor; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Apply the reflection API to obtain class information (class name, property, method, constructor, etc.) * * @author Cicada * @version 1.0 * @date 2021/8/8 23:47 */ public class Test01 { public static void main(String[] args) { String path = "cn.edu.chan.annotation.User"; try { Class clazz = Class.forName(path); //Gets the name of the class System.out.println(clazz.getName()); //Get package name + class name: CN edu. chan. annotation. User System.out.println(clazz.getSimpleName()); //Obtained class name: User //Get attribute information // Field[] fields = clazz.getFields(); // Only public fields can be obtained Field[] fields = clazz.getDeclaredFields(); //Get all field s Field f = clazz.getDeclaredField("username"); System.out.println(fields.length); for (Field temp : fields) { System.out.println("Properties:" + temp); } //Get method information Method[] methods = clazz.getDeclaredMethods(); Method m01 = clazz.getDeclaredMethod("getUsername", null); //If the method has parameters, the class object corresponding to the parameter type must be passed Method m02 = clazz.getDeclaredMethod("setUsername", String.class); for (Method m : methods) { System.out.println("method:" + m); } //Get constructor information Constructor[] constructors = clazz.getDeclaredConstructors(); Constructor c = clazz.getDeclaredConstructor(String.class, String.class, int.class); System.out.println("Get constructor:" + c); for (Constructor temp : constructors) { System.out.println("Constructor:" + temp); } } catch (Exception e) { e.printStackTrace(); } } }
result:
**cn.edu.chan.annotation.User User 3 Properties: private java.lang.String cn.edu.chan.annotation.User.username Properties: private java.lang.String cn.edu.chan.annotation.User.password Properties: private int cn.edu.chan.annotation.User.age method: public java.lang.String cn.edu.chan.annotation.User.toString() method: public void cn.edu.chan.annotation.User.setUsername(java.lang.String) method: public java.lang.String cn.edu.chan.annotation.User.getUsername() method: public int cn.edu.chan.annotation.User.getAge() method: public void cn.edu.chan.annotation.User.setPassword(java.lang.String) method: public void cn.edu.chan.annotation.User.setAge(int) method: public java.lang.String cn.edu.chan.annotation.User.getPassword() Get constructor: public cn.edu.chan.annotation.User(java.lang.String,java.lang.String,int) Constructor: public cn.edu.chan.annotation.User() Constructor: public cn.edu.chan.annotation.User(java.lang.String,java.lang.String,int)**
4. Dynamic operations through reflection API: constructor, method and attribute
package cn.edu.chan.myConstructor; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Apply the reflection API to obtain class information (class name, property, method, constructor, etc.) * * @author Cicada * @version 1.0 * @date 2021/8/8 23:47 */ public class Test01 { public static void main(String[] args) { String path = "cn.edu.chan.annotation.User"; try { Class clazz = Class.forName(path); //Gets the name of the class System.out.println(clazz.getName()); //Get package name + class name: CN edu. chan. annotation. User System.out.println(clazz.getSimpleName()); //Obtained class name: User //Get attribute information // Field[] fields = clazz.getFields(); // Only public fields can be obtained Field[] fields = clazz.getDeclaredFields(); //Get all field s Field f = clazz.getDeclaredField("username"); System.out.println(fields.length); for (Field temp : fields) { System.out.println("Properties:" + temp); } //Get method information Method[] methods = clazz.getDeclaredMethods(); Method m01 = clazz.getDeclaredMethod("getUsername", null); //If the method has parameters, the class object corresponding to the parameter type must be passed Method m02 = clazz.getDeclaredMethod("setUsername", String.class); for (Method m : methods) { System.out.println("method:" + m); } //Get constructor information Constructor[] constructors = clazz.getDeclaredConstructors(); Constructor c = clazz.getDeclaredConstructor(String.class, String.class, int.class); System.out.println("Get constructor:" + c); for (Constructor temp : constructors) { System.out.println("Constructor:" + temp); } } catch (Exception e) { e.printStackTrace(); } } }
result:
User{username='null', password='null', age='0'} Xiao Ming Xiao Wang Xiao Hong Xiao Hong
5. Get generic information through reflection
package cn.edu.chan.myConstructor; import cn.edu.chan.annotation.User; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; /** * Get generic information through reflection * @author Cicada * @version 1.0 * @date 2021/8/9 10:03 */ public class Test03 { public void test01(Map<String, User> map, List<User> list){ System.out.println("Test03.test01()"); } public Map<Integer,User> test02(){ System.out.println("Test03.test02()"); return null; } public static void main(String[] args) { try { //Gets generic information for the specified method parameter Method m = Test03.class.getMethod("test01", Map.class,List.class); //getGenericParameterTypes: returns - an array of type types whose method parameters are generic (parameterized type). Type [] Type[] t = m.getGenericParameterTypes(); for (Type paramType : t) { System.out.println("#"+paramType); //ParameterizedType is an interface that can be used to verify whether a generic type is parameterized if(paramType instanceof ParameterizedType){ //Gets the concrete type of the runtime generic Type[] genericTypes = ((ParameterizedType) paramType).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("Generic type:"+genericType); } } } //Gets the generic information of the return value of the specified method Method m2 = Test03.class.getMethod("test02", null); //getGenericReturnType: Return - returns an array of type types whose value is generic (parameterized type). Type [] Type returnType = m2.getGenericReturnType(); //ParameterizedType is an interface that can be used to verify whether a generic type is parameterized System.out.println("###"+returnType); if(returnType instanceof ParameterizedType){ //Gets the concrete type of the runtime generic Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("Return value, generic type:"+genericType); } } } catch (Exception e) { e.printStackTrace(); } } }
result:
#java.util.Map<java.lang.String, cn.edu.chan.annotation.User> Generic type: class java.lang.String Generic type: class cn.edu.chan.annotation.User #java.util.List<cn.edu.chan.annotation.User> Generic type: class cn.edu.chan.annotation.User ###java.util.Map<java.lang.Integer, cn.edu.chan.annotation.User> Return value, generic type: class java.lang.Integer Return value, generic type: class cn.edu.chan.annotation.User
Type is the high-level public interface of all types and, of course, the parent Class of Class.
They include primitive types, parameterized types, array types, type variables, and primitive types.