I annotation
annotation(Annotation): Not the program itself, it can explain the program or be read by other programs. Annotation format:@Note name, you can also add some parameters, such as:@SuppressWarnings(value="unchecked")
1. Built in annotation
Three commonly used built-in annotations: ① @Override : Override method. If it is found that its parent class or the referenced interface does not have this method, a compilation error will be reported. You can only modify methods. ② @Deprecated : Mark obsolete methods. The marked content is no longer recommended. You can modify methods, attributes, and classes. ③ @SuppressWarnings : Let the compiler"What it marks"Some warnings remain silent. You can modify classes and methods.
2. Meta annotation
The function of meta annotation is to annotate other annotations, that is, modify other annotations. Four common meta annotations: ① @Retention : How to save this annotation is only in the code(SOURSE),Or incorporated class In the file(CLASS), Or it can be accessed through reflection at runtime(RUNTIME). as@Retention(RetentionPolicy.SOURCE). SOURSE<CLASS<RUNTIME ② @Documented : Mark that these annotations will be included in the user document(JavaDoc)Yes. ③ @Inherited : The tag subclass can inherit the annotation of the parent class. ④ @Target : Mark the scope of use of this annotation. as@Target(value=ElementType.METHOD). TYPE Means that it can be marked"Class, interface (including annotation type) or enumeration declaration". FIELD Means that it can be marked"Field declaration". METHOD Means that it can be marked"method". PARAMETER Means that it can be marked"parameter". CONSTRUCTOR Means that it can be marked"Construction method". LOCAL_VARIABLE Means that it can be marked"local variable".
3. User defined annotation
use@Interface Custom annotation, inherited automatically java.lang.annotation.Annotation Interface. Each method actually declares a configuration parameter. The name of the method is the name of the parameter, and the return value type is the type of the parameter. Can pass default To declare the default value of the parameter If there is only one parameter member, the parameter name is generally declared as value Annotation element must have a value
Example of custom annotation:
public class Demo1DefineAnnotation { @MyAnnotation1(name = "Zhang San") // Each parameter must be assigned a value if it has no default value public void test1() {} @MyAnnotation2("Zhang San") // When there is only one parameter in the annotation and the parameter name is value, the parameter name can be omitted when writing public void test2(){} } @Inherited // Indicates that the subclass of the class modified by this annotation can inherit the annotation of the parent class @Documented // Indicates that annotations can be saved in JavaDoc @Target({ElementType.TYPE,ElementType.METHOD}) // Indicates that this annotation MyAnnotation1 can modify classes and methods @Retention(RetentionPolicy.RUNTIME) // Indicates that this annotation MyAnnotation1 can be saved to the program runtime @interface MyAnnotation1{ // Custom annotation String name(); // Annotation parameter, not method int age() default 0; // Set the default value of age to 0 } @interface MyAnnotation2{ // Custom annotation String value(); // When there is only one parameter member, the parameter name is generally declared as value }
II reflex
Reflection is the key to Java being regarded as a dynamic language. The reflection mechanism allows the program 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.
After loading the Class, an object of constant Class type (Class) is generated in the method area of heap memory (a Class has only one Class object), and this object contains complete Class structure information. We can see the structure of the Class through this object. This object is like a mirror. We can see the structure of the Class through this mirror, so we vividly call it reflection.
Class object is the root of Reflection. For any class you want to dynamically load and run, you have to obtain the corresponding class object first.
1. Method of obtaining Class object:
① Obtained by object: Class C1 = person getClass()
② Obtained by forname: class C2 = class forName(“Annotation.Student”)
③ Pass the class name Class: class C3 = student class
④ Type attribute of wrapper class through basic built-in type: class C4 = integer TYPE
// How to get the Class object public class TestReflection { public static void main(String[] args) throws ClassNotFoundException { Student student = new Student(); // Method 1: obtain through object Class c1 = student.getClass(); System.out.println(c1+"\t"+c1.hashCode()); //Party 12: forName obtained Class c2 = Class.forName("Annotation.Student"); System.out.println(c2+"\t"+c2.hashCode()); //Method 3: pass the class name Class get Class c3 = Student.class; System.out.println(c3+"\t"+c3.hashCode()); //Method 4: packing classes of basic built-in types have a Type attribute Class c4 = Integer.TYPE; System.out.println(c4); } } class Student {}
result:
class Annotation.Student 460141958 class Annotation.Student 460141958 class Annotation.Student 460141958 int
There is only one in the same class Class object
2. Common methods of class:
static Class forName(String name): Returns the specified class name name of Class object Object newInstance(): Return a Class Object instance String getName(): Return to this Class The name of the class represented by the object(Package name+Class name) String getSimpleName(): Return to this Class The name of the class represented by the object(Class name) Class getSuperClass(): Return to current Class Of the parent class of the object Class object Class[] getInterfaces(): Get current Class Object implemented interface ClassLoader getClassLoader(): Gets the class loader for this class Constructor[] getConstructors(): Get the object array of all constructors of this class Method getMethod(String name, Class<?>... parameterTypes): Returns the name of the object with the specified name and parameter type public Method object(Including the of inheriting the parent class, but excluding the constructor) Method[] getMethods(): Get all in the class public method(Including the of inheriting the parent class, but excluding the constructor) Method getDeclaredMethod(String name, Class<?>... parameterTypes): Returns the method object of the specified name and parameter type object of this class(Inheritance and construction methods are not included) Method[] getDeclaredMethods(): Get all methods of this class(And constructors that inherit from the parent class are not included) Field getField(String name): Returns the property specified in this class(Including inherited),This property must be public Field[] getFields(): Returns all the data in this class(Including inherited)Declared attribute object array, this field must be public Field getDeclaredField(String name): Returns the property specified in this class(Excluding inherited) Field[] getDeclaredFields(): Returns all the data in this class(Excluding inherited)Object array of declared properties
// Common methods of Class object public class Demo4Reflection { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("Annotation.Teacher"); //Get Class object // Get the name of the class System.out.println(c1.getName()); // Annotation.Teacher System.out.println(c1.getSimpleName()); // Teacher System.out.println("================================"); // Get the properties of the class System.out.println(c1.getField("name")); // Gets the specified public property System.out.println("---------------------------------"); Field[] fields = c1.getFields(); // Get all public properties including inheritance for (Field field:fields) { System.out.println(field+"\t"); } System.out.println("---------------------------------"); System.out.println(c1.getDeclaredField("age")); // Gets the property of the specified declaration System.out.println("---------------------------------"); fields = c1.getDeclaredFields(); // Get all properties excluding inheritance for (Field field:fields) { System.out.println(field); } System.out.println("================================"); // Method to get class System.out.println(c1.getMethod("setName",String.class)); // Gets the method of the object with the specified name and parameter type, including the inherited System.out.println("---------------------------------"); Method[] methods = c1.getDeclaredMethods(); // Get all methods excluding inheritance for (Method method:methods) { System.out.println(method); } System.out.println("================================"); //Gets the constructor of the class Constructor[] constructors = c1.getConstructors(); // Get all constructors of this class for (Constructor constructor:constructors) { System.out.println(constructor); } System.out.println("---------------------------------"); constructors = c1.getDeclaredConstructors(); // Get all constructors of this class for (Constructor constructor:constructors) { System.out.println(constructor); } System.out.println("---------------------------------"); // Gets the specified constructor System.out.println(c1.getConstructor(String.class,int.class,int.class,String.class)); } } class Person{ public String name; private int id; public Person() { } public Person(String name, int id) { this.name = name; this.id = id; } 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; } } class Teacher extends Person { private int age; String sex; public Teacher() { } public Teacher(String name, int id, int age, String sex) { super(name, id); this.age = age; this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
result:
Annotation.Teacher Teacher ================================ public java.lang.String Annotation.Person.name --------------------------------- public java.lang.String Annotation.Person.name --------------------------------- private int Annotation.Teacher.age --------------------------------- private int Annotation.Teacher.age java.lang.String Annotation.Teacher.sex ================================ public void Annotation.Person.setName(java.lang.String) --------------------------------- public int Annotation.Teacher.getAge() public java.lang.String Annotation.Teacher.getSex() public void Annotation.Teacher.setSex(java.lang.String) public void Annotation.Teacher.setAge(int) ================================ public Annotation.Teacher() public Annotation.Teacher(java.lang.String,int,int,java.lang.String) --------------------------------- public Annotation.Teacher() public Annotation.Teacher(java.lang.String,int,int,java.lang.String) --------------------------------- public Annotation.Teacher(java.lang.String,int,int,java.lang.String)
3. Which types have Class objects
class Class interface Interface[]Array enum Enumeration annotation Annotation, basic data type void etc.
public class TestReflection { public static void main(String[] args) { Class c1 = Object.class; // class Class c2 = Comparable.class; // Interface Class c3 = String[].class; // One dimensional array Class c4 = int[][].class; // Two dimensional array Class c5 = Override.class; // annotation Class c6 = ElementType.class; // enumeration Class c7 = Integer.class; // Basic data type Class c8 = void.class; // void Class c9 = Class.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); int[] a = new int[10]; int[] b = new int[5]; // As long as the element type and dimension are consistent, it is the same Class System.out.println(a.getClass().hashCode()+" "+b.getClass().hashCode()); } }
result:
class java.lang.Object interface java.lang.Comparable class [Ljava.lang.String; class [[I interface java.lang.Override class java.lang.annotation.ElementType class java.lang.Integer void class java.lang.Class 460141958 460141958
4. Class loading process
① Compilation: the code is first compiled into a binary bytecode file (. class file)
② Load: load the bytecode content of the class file into memory, convert the static data into the runtime data structure of the method area, and then generate a class object representing this class
③ 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: allocate memory for class variable (static) and set the default initial value of class variable
- Resolution: replace the symbolic reference (constant name) in the virtual machine constant pool with the direct reference (address)
④ Initialization: the process of executing the class constructor method. The class constructor method is generated by the combination of the assignment action of all class variables (static) in the class automatically collected during compilation and the statement of static code block (the class constructor constructs class information, not the constructor of this class object). When initializing a class, if it is found that its parent class has not been initialized, its parent class needs to be initialized first.
5. Class loader
The function of class loader is to load the class into memory, that is, load the bytecode content of class file into memory, convert the static data into the runtime data structure of method area, and then generate a class object representing this class.
There are three types of class loaders:
- Bootstrap classloader: it is the class loader of the JVM. It is responsible for the core library of the Java platform and is used to load the core class library. It cannot be obtained directly
- Extension classloader:
- System classloader: the most commonly used loader
Bootstap Classloader > Extension Classloader > System Classloader
// Class loader public class ClassLoader { public static void main(String[] args) throws ClassNotFoundException { // Get system class loader ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); // Get the parent class loader of the system class loader -- > extended class loader ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); // Get the parent class loader -- > root loader of the extended class loader ClassLoader parent1 = parent.getParent(); System.out.println(parent1); // Cannot get directly, output null // Test which class loader loads the current class ClassLoader classLoader = Class.forName("Annotation.ClassLoader").getClassLoader(); System.out.println(classLoader); // Test which loader loads the JDK built-in classes classLoader = Class.forName("java.lang.Object").getClassLoader(); // Root loader System.out.println(classLoader); } }
result:
sun.misc.Launcher$AppClassLoader@18b4aac2 sun.misc.Launcher$ExtClassLoader@1b6d3586 null sun.misc.Launcher$AppClassLoader@18b4aac2 null
Parental delegation mechanism: When a class is to be loaded, it will first System ClassLoader Check whether it has been loaded. If so, there is no need to load it again. If not, you will get the parent loader. Similarly, the parent class will first check whether it has been loaded. If not, go up. Notice this recursive process until you reach the Bootstrap classLoader Before, they were checking whether they had been loaded, and did not choose to load them themselves. until BootstrapClassLoader,There is no parent loader, so I start to think about whether I can load it. If you can't load, you will sink to the sub loader to load until the bottom. If there is no loader to load, it will be thrown ClassNotFoundException. Generally, custom classes are created by System ClassLoader load
6. What can a Class object do
① Dynamically create objects and call methods and properties through reflection
// Create objects dynamically through reflection // Invoke methods and properties through reflection public class Demo7 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class c1 = Class.forName("Annotation.User"); // Get Class object // Create an instance object through reflection User user = (User) c1.newInstance(); // Equivalent to calling a parameterless constructor System.out.println(user.toString()); // Creating instance objects through constructors Constructor constructor = c1.getDeclaredConstructor(int.class,String.class,int.class); user = (User) constructor.newInstance(10101,"Zhang San",18); System.out.println(user.toString()); // Call method through reflection Method setName = c1.getDeclaredMethod("setName", String.class); // Get the specified method setName of this class setName.invoke(user,"Li Si"); // invoke: Activate System.out.println(user); // Operation properties by reflection Field name = c1.getDeclaredField("name"); // You cannot directly operate the private attribute. You need to turn off the security detection of the program name.setAccessible(true); // Turn off security detection name.set(user,"Wang Wu"); // Equivalent to user Name = "Wang Wu" System.out.println(user.getName()); } } class User{ private int id; private String name; private int age; public User() { } public User(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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 "User{id="+this.id+",name="+this.name+",age="+this.age+"}"; } }
result:
User{id=0,name=null,age=0} User{id=10101,name=Zhang San,age=18} User{id=10101,name=Li Si,age=18} Wang Wu
Method,Field,Constructor All objects have setAccessible()Method to enable and disable access security checks Close safety check setAccessible(true)It can improve the efficiency of reflection execution
② Get annotation information
// Get annotation information through reflection public class Demo10 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("Annotation.User2"); //Get annotations through reflection Annotation[] annotations = c1.getAnnotations(); // Get all comments for (Annotation annotation:annotations) { System.out.println(annotation); } //Gets the parameter value of the annotation ClassAnnotation classAnnotation = (ClassAnnotation) c1.getAnnotation(ClassAnnotation.class); // Gets the specified annotation String value = classAnnotation.value(); System.out.println(value); //Gets the annotation for the specified attribute Field id = c1.getDeclaredField("id"); // Gets the specified property FieldAnnotation fieldAnnotation = id.getAnnotation(FieldAnnotation.class); System.out.println(fieldAnnotation); System.out.println(fieldAnnotation.name()); System.out.println(fieldAnnotation.type()); System.out.println(fieldAnnotation.Length()); } } @ClassAnnotation("User2") class User2{ @FieldAnnotation(name = "id",type = "int",Length = 10) private int id; @FieldAnnotation(name = "name",type = "String",Length = 5) private String name; @FieldAnnotation(name = "age",type = "int",Length = 10) private int age; public User2() { } public User2(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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 "User2{id="+this.id+",name="+this.name+",age="+this.age+"}"; } } // Class annotation @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface ClassAnnotation{ // Custom annotation String value(); // parameter } // Attribute annotation @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface FieldAnnotation{ String name(); // Parameter: attribute name String type(); // Parameters: attribute types int Length(); // Parameters: attribute length }
result:
@Annotation.ClassAnnotation(value=User2) User2 @Annotation.FieldAnnotation(name=id, type=int, Length=10) id int 10