Life cycle: the process from project approval to software deactivation
- Problem definition and planning: this stage is a joint discussion between the software developer and the demander, mainly to determine the software development objectives and their feasibility
- Requirement analysis: when it is determined that the software development is feasible, the functions to be realized by the software shall be analyzed in detail. Requirements analysis stage is a very important stage. If this stage is well done, it will lay a good foundation for the success of the whole software development project.
- Software design: at this stage, the whole software system is divided into large and small modules according to the results of demand analysis, and the specific structure of each module is designed. Such as system framework design, database design, etc. Software design is generally divided into overall design and detailed design.
- Program coding: this stage is to convert the results of software design into program code that can be run by the computer. In program coding, it is necessary to formulate unified and standard writing specifications. To ensure the readability and maintainability of the program and improve the operation efficiency of the program.
- Software testing: after the completion of software design, rigorous testing shall be carried out to find and correct the problems existing in the whole design process. The whole test process is divided into three stages: unit test (white box), integration test (black box, function test, strength performance test) and system test. There are two main test methods: white box test and black box test. In the test process, it is necessary to establish a detailed test plan and test in strict accordance with the test plan to reduce the randomness of the test.
- Operation and maintenance: install and deploy the software system, repair the bug s in the software and upgrade the system. After the software development is completed and put into operation, the software can not continue to meet the requirements of users due to various reasons. In order to extend the service life of software, it is necessary to maintain the software. Software maintenance includes error correction maintenance and improvement maintenance
In order to improve software development efficiency and reduce software development cost, an excellent software system should have the following characteristics:
- Reusability: following DRY(Don't Repeat Yourself Principle) Principle to reduce duplicate code in software.
- Expandability: when the software needs to be upgraded and added with new functions, it can easily create new modules on the existing system architecture without changing the existing structure of the software or affecting the existing modules.
- Maintainability: when user requirements change, you only need to modify a small amount of code in the local module
- High cohesion: cohesion emphasizes the functional relationship within a system module. Each module only completes specific functions, and there will be no functional overlap between different modules. High cohesion can improve the reusability and maintainability of software.
- Low coupling: coupling emphasizes the relationship between multiple modules. Modules are independent of each other. Modifying one module will not affect other modules. Low coupling improves the maintainability of software.
Basic naming rules: use meaningful English words, and multiple words are represented by hump
Package name
All lowercase, domain name inverted. Module name. Component name, for example: com.util
Interface name
Capital letters, adjectives, adverbs. Habitually starts with an I. At this time, I means interface, see the meaning of the name. (not mandatory, it should be considered in combination with other specifications), for example: IUserService , IEmployeeService
Interface implementation class
Habitual inertia ends with Impl (not mandatory, it should be considered in combination with other specifications), for example: UserServiceImpl , EmployeeServiceImpl
Class name
Initial capital, noun. Follow the hump representation. For example: User , Employ
Method name
Initial lowercase. Strive for clear semantics and use multiple words. Follow the hump representation. For example: getUserInfoByName()
Variable name
Initial lowercase. Follow the hump representation. For example: userInfo
Constant name
All uppercase, strive to be semantically clear, and use multiple words. Use underline segmentation. For example: MAX_STOCK_COUNT.
2, Software testingSoftware testing is often divided into two categories: black box testing and white box testing.
2.1 black box testBlack box test, also known as function test, is to test whether each function can be used normally, regard the program as a black box that cannot be opened, test on the program interface without considering the internal structure and internal characteristics of the program, and check whether the program function can be used normally according to the requirements specification.
Simply put, you don't need to write code to input values to see whether the program can output the expected values.He mainly found the following mistakes:
- Is the function incorrect or missing
- Is there any error in the interface
- Input and output errors
- Database access error
- Is there a performance problem
- Initialization and termination errors, etc
It is tested by developers. It is also called structure test, transparent box test, logic driven test or code based test. It is a test program according to the internal structure of the program to detect whether the internal action of the product is normally executed according to the provisions of the design specification. The tester must check the internal structure of the program and obtain the test data from the logic of the program.
Simply put: you need to write code. Pay attention to the specific execution process of the program. 2.3 JUnit testJUnit is a regression testing framework written by Erich Gamma and Kent Beck. JUnit tests are programmer tests, White box test , Because the programmer knows How and What the tested software does.
2.3.1 JUnit dependent installationSince JUnit 4 regression testing framework is provided by a third party and is not provided by JDK, it is necessary to import other people's jar packages and install corresponding plug-ins. Here, take maven as an example, import maven coordinates:
<!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> Copy code2.3.2 JUnit common notes
JUnit with some common annotations can solve the problem of code duplication
2.3.2.1,@BeforeDecorated methods are automatically executed before testing methods
2.3.2.2,@AfterThe modified method will be automatically executed After the test method is executed. If there are exceptions, the code After @ After will also be executed
3, Configuration fileIt is reasonable to say that as long as some configuration information can be saved for the program to dynamically read data, it is OK. However, in order to improve efficiency, it is customary to use two files with special characteristics as configuration files in the IT industry
- properties file
- XML file
The file is called property file / resource file / configuration file, with properties as the file suffix. The access feature is the format of KV key value pair: key=value, Multiple pairs of data are separated by line breaks .
matters needing attention:- In the configuration file, all data is strings, and quotation marks are not required.
- Spaces are not required in the configuration file
If we want to read the data in properties, we use IO operation to read row by row, and then = To segment strings can also be completed. However, it is still troublesome. If there are more troublesome comments, we can realize such complex steps. SUN company must have written tools and methods for us. This is Properties .
Properties Is the implementation class of map. You can inherit the common operation methods of map (get,put....) , map We generally don't use the methods in. Because the properties file is special, we usually use them Properties Class.
3.1.2 common API spublic void load(InputStream inStream); public String getProperty(String key);
package com.test; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * @author Xiao_Lin * @date 2020/12/28 11:55 */ public class ProTest { public static void main(String[] args) throws IOException { //Read data from configuration file Properties properties = new Properties(); //In order to get the ClassLoder object, it has nothing to do with Thread ClassLoader loader = Thread.currentThread().getContextClassLoader(); //Read the configuration file through the class loader and return an input stream InputStream stream = loader.getResourceAsStream("user.properties"); //Load profile properties.load(stream); System.out.println(properties.getProperty("user")); System.out.println(properties.getProperty("password")); } } Copy code3.2. XML file
XML(Extensible Markup Language) is an extensible markup language (enclosed by ◇ >). XML technology was published by W3C Organization (World Wide Web Consortium). At present, it follows that W3C organization published in 1998.
XML1.0 specification. Its design purpose is to transmit data rather than display data (HTML). Its tags are not predefined and need to define their own tags. It is a W3C recommended standard.
3.2.1 why learn XML- XML is a general data exchange format.
- Many system configuration files use XML.
- Java EE frameworks are basically using XML
- An XML document needs to be declared on the first line of the document, which represents
During the operation of the program, through Bytecode file Dynamically obtain the member information (constructor, method and field) in the class, which is called reflection. The purpose is to create objects, obtain methods and call them through the program automatic acquisition constructor.
4.2 bytecode objectJava code goes through three stages:
We can find their commonalities through multiple objects and abstract them into a class. The class is the template of the object, and each entity is the object
Bytecode is also a real file. Each bytecode is an instance. To store these bytecodes, the JVM needs to abstract them into templates, and then create objects through templates to store the information of each bytecode. When you want to use a byte code (for example, create a Person object), extract the Class object that contains the Person.class content from JVM, and then instantiate the Person object. three
Class is defined in JDK: java.lang.Class , There are a large number of methods beginning with gte in this class, which means that bytecode objects can be used to obtain information. Therefore, when we get the bytecode object, we can directly operate the constructors, methods, fields, etc. in the current bytecode.
4.3. Get bytecode objectThrough the API, we can know that Class does not have a public constructor because the Class object is automatically built by the Java virtual machine when loading the Class.
Mode 1
Through Class forName() Method to obtain the bytecode object * * (common) * *, which is mostly used in the configuration file to define the Class name in the configuration file. Read files, load classes and various popular frameworks.
Class.forName(String className); //The bytecode object is obtained through the fully qualified name of the class. The fully qualified class name is package name + type Class.forName("java.lang.String"); //Returns if it exists in the JVM, and throws an exception if it does not exist Copy code
Mode II
The bytecode object is obtained through the getClass() method of the object, which is mostly used to obtain the bytecode of the object.
new User().getClass(); //Through the getClass method in the parent class Object Copy code
Mode III
The bytecode object is obtained through the class field of type (basic type), which is mostly used for parameter passing.
int.class; Copy code
summary
- The first of the above three methods is the most used, which is used in various frameworks.
- The same bytecode file (*. class) will only be loaded once during a program run, The class object obtained by either method is the same.
@Test public void testGetClass() throws Exception { // 1. Pass the fully qualified name of the class Class.forName(); Class clz1 = Class.forName("cn.linstudy.domain.Person"); // 2 through the getClass() method of the object Person p = new Person(); Class clz2 = p.getClass(); // 3 get through the class field Class clz3 = Person.class; // The bytecode will be loaded only once. No matter which way to obtain the bytecode, it is the same System.out.println(clz1 == clz2); //true System.out.println(clz2 == clz3); //true System.out.println(clz1 == clz3); //true // Int type and int data type are not the same System.out.println(int.class); System.out.println(int[].class); } Copy code4.4. Get constructor
The purpose of using reflection is to use the program to dynamically manipulate the members of the class, such as methods, and the operation method must first have an object, which is created through the constructor, so the constructor must be obtained first.
4.4.1 get all constructors public Constructor<?> [] getConstructors(); : obtain All public decorated constructors .
public Constructor<?> [] getDeclaredConstructors(); : Get all constructors (including non-public)
4.4.2. Get the specified constructor public Constructor getConstructor(Class... parameterTypes);
public Constructor getDeclaredConstructor(Class...parameterTypes)
parameterTypes: the type of the parameter (the type of the parameter list of the constructor)
conclusion
With s means to obtain multiple permissions. With Declared means to ignore permissions, including private permissions.
4.4.3. Get constructor exercise@Test public void testGetConstructor() throws NoSuchMethodException { // Get bytecode object Class clz = Person.class; // 1 get all public constructors Constructor[] cons1 = clz.getConstructors(); for(Constructor con : cons1){ System.out.println(con); } System.out.println("--------"); // 2 get all constructors, including private Constructor[] cons2 = clz.getDeclaredConstructors(); for(Constructor con : cons2){ System.out.println(con); } // 3 get parameterless constructor Constructor con1 = clz.getConstructor(); System.out.println(con1); // 4 get constructor with parameters Constructor con2 = clz.getConstructor(Long.class, String.class); System.out.println(con2); // 5 get the specified private constructor Constructor con3 = clz.getDeclaredConstructor(String.class); System.out.println(con3); } Copy code
Common errors
The parameters do not match and an error is reported. The specified constructor cannot be found
4.4.4. Call constructor to create objectpublic Object newInstance(Object... initargs);// initargs: the actual parameters passed by calling the constructor. The parameter list must match (type, number, order) Copy code
@Test public void testCreateObject() throws Exception { // Get bytecode object Class clz = Class.forName("cn.linstudy.domain.Person"); // Gets the constructor with parameters. The parameters are parameter types Constructor con1 = clz.getConstructor(Long.class, String.class); //Invoking Constructors Object obj = con1.newInstance(1L, "Wolf"); System.out.println(obj); // Gets the private constructor with parameters Constructor con2 = clz.getDeclaredConstructor(String.class); // To call a private constructor, you must first set it to be accessible con2.setAccessible(true); Object obj2 = con2.newInstance("Small size"); System.out.println(obj2); } Copy codeNote: you cannot directly access members without permission (non-public). If you want to use reflection to operate non-public members, you must set an accessible flag
We tried to privatize the constructor to create the object, and were told that the permissions were insufficient
The solution is as follows:
public void setAccessible(boolean flag) : Pass a true to indicate that you can access, regardless of permission
From the API, we can find that, Constructor,Field,Method yes AccessibleObject Because these three members can be modified by the access private modifier.
package com.test.reflect; import java.lang.reflect.Constructor; /** * @author Xiao_Lin * @date 2020/12/28 20:17 */ public class TestReflect { public static void main(String[] args) throws Exception { Class<?> student = Class.forName("com.test.reflect.Student"); System.out.println(student); Constructor<?> constructor = student.getDeclaredConstructor(String.class); constructor.setAccessible(true); Object zs = constructor.newInstance("Zhang San"); System.out.println(zs); } } Copy code
As long as you see the incoming fully qualified name, you basically use reflection to obtain the bytecode object through the fully qualified name. As long as you see that there is no specified constructor but the object can be created, you basically use the bytecode object newInstance To create objects
4.5 acquisition method 4.5.1. Obtain all methodspublic Method[] getMethods(); public Method[] getDeclaredMethods();4.5.2. Obtain the specified method
- public Method getMethod(String name, Class<?>... parameterTypes);
- public Method getDeclaredMethod(String name, Class<?>... parameterTypes) : Name: method name, parametertypes: the type of the parameter list of the current method. Note that to find a specified method, you must use method signature to locate it. Method signature = method name + parameter list. The experience is the same as that of the constructor. With s means to obtain multiple, and with declared means to ignore access permissions.
@Test public void testGetMethod() throws Exception { /** 1 Get all public methods, including the of the parent class 2 Get all methods, including private, excluding the parent class 3 Gets the public method of the specified parameter, including the name of the parent class 4 Gets the private method of the specified parameter, excluding the of the parent class **/ // 1 get bytecode object Class clz = Class.forName("cn.linstudy.domain.Person"); // 2 get constructor to create object // 3 acquisition method //1 get all public methods, including the of the parent class Method[] methods = clz.getMethods(); for(Method m : methods){ System.out.println(m); } System.out.println("---------"); //2 get all methods, including private, excluding the parent class Method[] methods2 = clz.getDeclaredMethods(); for(Method m : methods2){ System.out.println(m); } System.out.println("---------"); //3 get the public method of the specified parameter, including the method of the parent class Method sayHelloMethod = clz.getMethod("sayHello", String.class); System.out.println(sayHelloMethod); //4 get the private method of the specified parameter, excluding the of the parent class Method doWorkMethod = clz.getDeclaredMethod("doWork", String.class); System.out.println(doWorkMethod); } Copy code4.6 calling method
public Object invoke(Object obj, Object... args); :
obj: indicates the object to be used when calling this method
args: the actual parameter of the calling method. The return value of the method indicates whether the method has a return value. If so, it will return. If not, it will return null.
Traditional call method
Student t = new Student(1, "Zhang San"); t.sleep(5);// Zhang San, sleep for five hours. Copy code
Create objects and call methods using reflection
Method m = clz.getMethod("sleep", int.class);// Find sleep method. m.invoke(obj, 5);// Sleep for five hours. Copy code
public class Person { private Long id; private String name; public Person() { } public Person(Long id, String name) { this.id = id; this.name = name; } private Person(String name) { this.name = name; } public void sayHello(){ System.out.println("hello"); } public String sayHello(String name){ System.out.println(name + ": hello"); return "Hello!"; } public static void sayHello(String name,Long id){ System.out.println("Call static method"); } private void doWork(){ System.out.println("doWork"); } private void doWork(String name){ System.out.println(name + ": doWork"); } // getter method setter method public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + '}'; } } Copy code
@Test public void testGetMethod() throws Exception { // 1 get bytecode object Class clz = Class.forName("com.reflect.Person"); // 2 get constructor to create object Object obj = clz.newInstance(); // Use a common parameterless constructor // 3 acquisition method //1 get all public methods, including the of the parent class Method[] methods = clz.getMethods(); for(Method m : methods){ System.out.println(m); } System.out.println("---------"); //2 get all methods, including private, excluding the parent class Method[] methods2 = clz.getDeclaredMethods(); for(Method m : methods2){ System.out.println(m); } System.out.println("---------"); //3 get the public method of the specified parameter, including the method of the parent class Method sayHelloMethod = clz.getMethod("sayHello", String.class); System.out.println(sayHelloMethod); // Call method Object val1 = sayHelloMethod.invoke(obj, "Zhang San"); System.out.println("Value 1:" + val1); //4 get the private method of the specified parameter, excluding the of the parent class Method doWorkMethod = clz.getDeclaredMethod("doWork", String.class); System.out.println(doWorkMethod); // Set accessibility doWorkMethod.setAccessible(true); // Call private methods doWorkMethod.invoke(obj,"Li Si"); // Call static method Method staticSayHelloMethod = clz.getDeclaredMethod("sayHello", String.class, Long.class); // You don't need an object to call, but you must add null to the parameter, otherwise you will use the following parameter as the object of the calling method staticSayHelloMethod.invoke(null,"Xiao Ming",1L); } Copy codebe careful:
- Methods can also be modified by access private modifiers. Therefore, if you want to access non public modified methods, you need to set the accessibility before accessing method.setAccessible(true); .
- If you call a static method, you do not need an object, so at this time, in the first parameter of the invoke method, the object directly passes a null.
public Field getField(String name); :
public Field getDeclaredField(String name);
Name the name of the field to get
4.7.2. Get all fieldspublic Field[];
getFields() ;
public Field[] getDeclaredFields();
@Test public void testField() throws Exception { // 1 get bytecode object Class clz = Person.class; Object obj = clz.newInstance(); // 2 get field Field[] fs = clz.getFields(); for(Field f: fs){ System.out.println(f); } Field[] fs2 = clz.getDeclaredFields(); for(Field f: fs2){ System.out.println(f); } // Get a single field Field nameField = clz.getDeclaredField("name"); System.out.println(nameField); } Copy code4.8. Operation field
get(Object obj);
set(Object obj,Object value);
// Set private fields accessible nameField.setAccessible(true); // Action name field // Set the data of the field nameField.set(obj,"Wolf"); // Get the data of the name field Object nameValue = nameField.get(obj); System.out.println(nameValue); Copy code5, Introspection 5.1,JavaBean
JavaBean is the most important reusable component in Java (reduce code duplication, reuse, encapsulate business logic, encapsulate data).
5.1.1 specification requirements for JavaBean s- Use public decoration.
- Field privatization.
- Provide get/set methods.
- Public parameterless constructor (use reflection and bytecode object. newInstance to create object).
- event
- method
- attribute
JavaBean s can encapsulate data by saving the data into the properties of a bean object.
The property is not a field. The property is derived through the get/set method.
* * standard get method / get method / read method: * * public modifier, no parameter, return, start with get.
* * standard set method / set method / write method: * * public modifier, with parameters, no return, start with set.
Note:
- As long as it is a standard get/set method, there are properties. It does not have to be a standard writing method automatically generated by tools.
- The field is boolean, and the reading method starts with is instead of get.
JavaBean is a very commonly used component, which is nothing more than the properties in the operation. Previously, we wanted to obtain the methods in JavaBean. If reflection is used, it is very troublesome, so SUN company provided a set of API for operating JavaBean properties: introspection ( Introspector ).
5.3 the role of introspection- Get relevant status information such as attribute name and attribute type.
- Obtain the read-write method corresponding to the property, and operate the value of the property.
- Get the description object of JavaBean through bytecode object, and return the description object of JavaBean public static BeanInfo getBeanInfo(Class beanClass, Class stopClass);
- Get the property descriptor through the JavaBean description object PropertyDescriptor[] getPropertyDescriptors();
- Get the property name, property type and property name through the property descriptor, and get the property name through the read-write (getter/setter) method: public String getName(); get attribute type: Public class <? > getpropertytype(); get read method (getter): public Method getReadMethod(); get write method (setter): public Method getWriteMethod();
When obtaining BeanInfo objects through bytecode objects, the information of the current bytecode Object and all its parent classes will be introspected by default. For example: getBeanInfo(A.class) , In fact, it will also introspect the parent class of a, such as the information of Object. Generally speaking, we don't care about the attribute related information of the parent class. At this time, we can call the overloaded method of getbeaninfo: getBeanInfo(beanClass,stopClass) .
Demonstration: BeanInfo beanInfo = Introspector.getBeanInfo(Person.class,Object.class);
package com.day03.IntrospectorDemo; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; /** * @author Xiao_Lin * @date 2020/12/29 13:37 */ public class TestIntrospector { public static void main(String[] args) throws Exception { //create object Student student = Student.class.newInstance(); //Convert JavaBean to beanInfo BeanInfo beanInfo = Introspector.getBeanInfo(student.getClass(),Object.class); //Get all properties through beanInfo PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); //Traverse the attribute descriptor array to get each attribute descriptor for (PropertyDescriptor pd : propertyDescriptors) { //Get property name System.out.println("Attribute name = " + pd.getName()); //Get property type System.out.println("Attribute type = " + pd.getPropertyType()); //Get the getter/setter method of the property Method getMethod = pd.getReadMethod(); System.out.println("get method = " +getMethod); Method setMethod = pd.getWriteMethod(); System.out.println("set method = " +setMethod); //Call the set method of the age property if ("age".equals(pd.getName())){ //Execute the set method of age. The invoke parameter means which object is given which value setMethod.invoke(student,22); } //Execute the get method again System.out.println(student.getAge()); } } } Copy code5.5 transformation between JavaBean and Map
The structure of map and JavaBean is very similar. We can convert map and JavaBean to each other, and correspond the key and attribute name one by one
5.5.1. JavaBean to map// Java bean to map public static Map<String, Object> BeanToMap(Object obj) throws Exception{ Map<String, Object> map = new HashMap<>(); //Get all attributes through introspection BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { //Get attribute name as key String key = pd.getName(); //Get the getter method of the property and call Object value = pd.getReadMethod().invoke(obj); map.put(key, value); } return map; } Copy code
public class BeanMap { public static void main(String[] args) throws Exception{ Map<String, Object> map = BeanToMap(new Student("Zhang San", 20)); map.forEach((k,v)-> System.out.println(k+"->"+v)); } } Copy code5.5.2 map to JavaBean
//map to JaveBean, where generics are used public static <T> T MapToBean(Map<String, Object> map ,Class<T> clz) throws Exception{ //Create JavaBean object T t = clz.newInstance(); //Traverse the property, get the property name as the key of mao, get the value value, and then set it to the setter method //Get all properties BeanInfo beanInfo = Introspector.getBeanInfo(clz, Object.class); PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { String key = pd.getName(); Object value = map.get(key); pd.getWriteMethod().invoke(t,value); } return t; } Copy code6, Annotation 6.1 introduction to notes
We can use annotations to modify the member information in the class. Annotation s are actually annotations.
6.2 definition format@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Annotation name { } Copy code
Define format: @ interface annotation name
Use format: @ Annotation name (attribute name = attribute value, attribute name = attribute value)
Annotations are pasted on program elements. If you want to have some functions, There must be three roles involved :
- Annotation itself
- Pasted program elements
- The third-party program uses reflection to give function to the annotation (behind the annotation, there must be a piece of code to give function to the annotation).
@Override @Deprecated @SuppressWarings @Functionallnterface6.4 meta annotation
annotation : A tag used to paste on classes / methods / variables. Third party programs can give certain functions through this tag.
Meta annotation : The annotation used to post on the annotation when defining the annotation is used to limit the usage of the annotation. He included three notes
6.4.1,@TargetIndicates where the annotation can be pasted (on classes, methods, constructors, etc.) ElementType Enumeration class.
ElementType.ANNOTATION_TYPE ElementType.CONSTRUCTOR ElementType.FIELD ElementType.LOCAL_VARIABLE ElementType.METHOD ElementType.PACKAGE ElementType.PARAMETER ElementType.TYPE6.4.2,@Retention
Indicates the period in which the annotation can be saved. The value of the period is encapsulated in the RetentionPolicy enumeration class.
6.4.3,@DocumentedUse @ Documented The labeled label is saved to the API document.
6.4.4,@Inherited @ Inherited Labels of labels can be inherited by subclasses.
The tag is obsolete and is not recommended. Before JDK5, use document comments to mark obsolete
@SuppressWarings @Functionallnterface6.4 meta annotation
annotation : A tag used to paste on classes / methods / variables. Third party programs can give certain functions through this tag.
Meta annotation : The annotation used to post on the annotation when defining the annotation is used to limit the usage of the annotation. He included three notes
6.4.1,@TargetIndicates where the annotation can be pasted (on classes, methods, constructors, etc.) ElementType Enumeration class.
ElementType.ANNOTATION_TYPE ElementType.CONSTRUCTOR ElementType.FIELD ElementType.LOCAL_VARIABLE ElementType.METHOD ElementType.PACKAGE ElementType.PARAMETER ElementType.TYPE6.4.2,@Retention
Indicates the period in which the annotation can be saved. The value of the period is encapsulated in the RetentionPolicy enumeration class.
6.4.3,@DocumentedUse @ Documented The labeled label is saved to the API document.
6.4.4,@Inherited @ Inherited Labels of labels can be inherited by subclasses.