1: Class loading
Class life cycle in memory: load -- > use -- > unload
1.1: class loading process
(1) Loading: load
Refers to reading clas bytecode data of type into memory. Get the binary data stream of the class through the full name of the class.
The binary data stream of the parsing class is the data structure in the method area
Create an instance of the java.lang.Class class class to represent the type. As the access entry of various data of this class in the method area
(2) Connection: link Prepare: prepare the corresponding memory
Prepare the corresponding memory (method area), create Class objects, assign default values to Class variables and initial values to static constants.
Parsing: converts symbolic references to classes, interfaces, fields, and methods to direct references
(3) Initialization: initialize
1.2: class loader
Different classes need different class loaders to load
1. Boot class loader Bootstrap Load core class library String Integer jre/lib rt.jar String Math It is not implemented in Java code, nor is it a subclass of ClassLoader. When obtaining its object, it often returns null 2. Extension class loader ExtClassLoader jre/lib/ext/ *jar 3. Application Loader AppClassLoader Self written class animal cat dog student 4. Custom class loader For example: tomcat
be careful:
Get the class loader 1. Get the class loader using the runtime type 2. Use the runtime type. getClassLoader(); 3. The father of the application loader is the extension class loader. The father of the extension class loader is the boot class loader. 4. Parental delegation
1.3: acquisition of class loader
To obtain the Class loader, first obtain the runtime Class (getClass(), etc.) to obtain large Class objects, and then obtain the Class loader (getClassLoader()) according to the runtime Class
@Test public void test04(){ Person person = new Person(); Class<? extends Person> aClass = person.getClass(); ClassLoader classLoader = aClass.getClassLoader(); System.out.println("Application Loader = " + classLoader);//AppClassLoader ClassLoader extClassLoade = classLoader.getParent();//ExtClassLoade System.out.println("parent = " + extClassLoade); ClassLoader parent = extClassLoade.getParent(); System.out.println("parent = " + parent);//null } @Test public void test03(){ Person person = new Person(); //Get application class loader Class<? extends Person> aClass = person.getClass(); ClassLoader classLoader = aClass.getClassLoader(); System.out.println("classLoader = " + classLoader); } @Test public void test02() throws ClassNotFoundException { //1. Get boot class loader Class<?> aClass = Class.forName("com.sun.nio.zipfs.ZipCoder"); //extensions class loader ClassLoader classLoader = aClass.getClassLoader(); System.out.println("classLoader = " + classLoader); //Get boot class loader ClassLoader parent = classLoader.getParent(); System.out.println("parent = " + parent); } @Test public void test01(){ //1: Get boot class loader //Because the String is under the core package, it is loaded by the boot class loader String s = "Hello"; //Get runtime type Class<? extends String> aClass = s.getClass(); //Get loader ClassLoader classLoader = aClass.getClassLoader(); // The boot class loader itself is not implemented in Java code, nor is it a subclass of ClassLoader. When obtaining its object, it often returns null System.out.println("classLoader = " + classLoader); }
2: Class initialization:
Initialization: assign values to static member variables in the class
1. Static member variable display assignment statement
2. Static code block content
2.1: what operations will cause class initialization?
(1) To run the class where the main method is located, first complete the class initialization, and then execute the main method
(2) Create this type of object
(3) Call the static members (class variables and class methods) of a class. If the class is not initialized, complete the class initialization first
(4) As long as a subclass needs to be initialized during inheritance, if it is found that its parent class has not been initialized, the parent class must be initialized first.
(5) When a class is operated through reflection, if the class is not initialized, it will also cause the class to initialize first
Class initialization executes < clinit > (), which consists of (1) the explicit assignment code of class variables (2) the code in the static code block
public class Person { public final static double salary =9999.9; static int age = 20; static { System.out.println("this is Person static Code block"); } public void add(){ } public static void show(){ System.out.println("this is static show()"); } public static void main(String[] args) { } } class Son extends Person{ static { System.out.println("this is Son static Code block"); } static double weight = 100.0; public static void showMessage(){ System.out.println("this is son static showMessage()"); } }
Some operations have initialization lag? Initialization lag: the use of resources does not lead to the initialization of this class (it needs to be understood according to the loading order of resources. If it is loaded and called with the class information, it may cause the class after initialization)
@Test public void test02(){ //When a subclass directly calls the static resources of the parent class, the instantiation of the subclass will lag //Because class loading takes precedence over instantiation, the information of parent and child classes has been loaded //And the static resources are also loaded with the loading of the class, so the subclass does not need to be initialized at this time // Son.show(); //Calling constant information directly by the parent class name will also cause the initialization of the parent class to lag //Because constants are determined at the join stage /*double age = Person.salary; System.out.println("age = " + age);*/ //Creating an array of classes will also cause after class initialization Person[] ps = new Person[3]; } @Test public void test01() throws ClassNotFoundException { //Reflection can cause the parent class to initialize and then the child class to initialize // Class<?> aClass = Class.forName("com.atguigu.load.Son"); //Parent class instance // Person person = new Person(); //Advanced class initialization, code in the execution method. // Person.show(); Son.showMessage(); System.out.println("------"); Son.showMessage(); }
3: parents delegate mode of Java system class loader
If the Class loader at the next level receives a task, it will first search whether it has been loaded. If not, it will upload the task first. If it has not been loaded, it will go all the way to the root loader. If the root loader is not found in its responsible path, it will send back. If it is not found all the way back to the last level, it will report ClassNotFoundException or NoClassDefError, If it is found at a certain level, it directly returns the Class object.
1. The advantage of adopting the two parent delegation mode is that the Java class has a hierarchical relationship with priority along with its class loader. Through this hierarchical relationship, the repeated loading of the class can be avoided. When the father has loaded the class, it is not necessary to load the child ClassLoader again.
2. Safe. The types defined in the Java core API will not be replaced at will. Suppose a class named java.lang.Integer is passed through the network and passed to the startup class loader through the parental delegation mode. The startup class loader finds the class with this name in the core Java API and finds that the class has been loaded, and will not reload the java.lang.Integer passed through the network, And directly return the loaded Integer.class, which can prevent the core API library from being tampered with at will.
The application class loader regards the extension class loader as the parent loader,
The extension class loader treats the boot class loader as the parent loader.
4: Uninstall of class:
1: All instances of this class have been recycled;
2: The ClassLoader that loaded this class has been recycled
3: The java.lang.Class object corresponding to this class is not referenced anywhere, and the methods of this class cannot be accessed anywhere through reflection.
If the above three conditions are met, the JVM will perform GC garbage collection
5: javalang.Class class
5.1: java reflection mechanism
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 obtained information and the function of dynamically calling object methods are called the reflection mechanism of Java language.
The Class object is the source of reflection.
5.2: which types can get Class objects
All runtime types
//(1) Basic data type and void
For example: int.class
void.class
//(2) Classes and interfaces
For example: String.class
Comparable.class
//(3) Enumeration
For example: ElementType.class
//(4) Annotation
For example: Override.class
//(5) Array
For example: int[].class
5.3: four ways to obtain Class objects:
(1) Type name.class All types
(2) Object. getClass()
(3) Class. Forname (full name of type)
(4) ClassLoader's ClassLoader object. Loadclass (type full name)
@Test public void test04() throws ClassNotFoundException { Class catClass = Cat.class; ClassLoader classLoader = catClass.getClassLoader(); //It is cumbersome. This method is generally not used Class<?> aClass = classLoader.loadClass("com.atguigu.clazz.Dog"); System.out.println("aClass = " + aClass); } @Test public void test03() throws ClassNotFoundException { Class<?> aClass = Class.forName("com.atguigu.load.Person"); System.out.println("aClass = " + aClass); } @Test public void test02(){ Class<String> stringClass = String.class; System.out.println("stringClass = " + stringClass); Class<Integer> integerClass = int.class; System.out.println("integerClass = " + integerClass); Class<Void> voidClass = void.class; System.out.println("voidClass = " + voidClass); Class<int[][]> aClass = int[][].class; System.out.println("aClass = " + aClass); } @Test public void test01(){ Dog dog = new Dog(); Class<? extends Dog> aClass = dog.getClass(); System.out.println("aClass = " + aClass); Cat cat = new Cat(); Class<? extends Cat> aClass1 = cat.getClass(); System.out.println("aClass1 = " + aClass1); } }
6: Reflection get information
Attribute object Field . Set (object, value)
Method object Method . Invoke (object) (parameterless method)
perhaps . Invoke (object, parameter value) (parametric method, deformable parameter)
6.1: get class information (father, implemented interface, permission modifier, package name)
@Test public void test02() throws ClassNotFoundException { Class<?> aClass = Class.forName("com.atguigu.reflect.some.Cat"); //Get permission modifier int modifiers = aClass.getModifiers(); System.out.println("modifiers = " + modifiers); String string = Modifier.toString(modifiers); System.out.println("string = " + string); } @Test public void test01(){ Class<Cat> catClass = Cat.class; //Get package name Package aPackage = catClass.getPackage(); System.out.println("aPackage = " + aPackage); //Get parent class Class<? super Cat> superclass = catClass.getSuperclass(); System.out.println("superclass = " + superclass); //Get implementation interface Class<?>[] interfaces = catClass.getInterfaces(); for (Class<?> in : interfaces) { System.out.println("in = " + in); } }
be careful:
The obtained permission modifiers have corresponding numbers, and Modifier.toString(modifiers) is required;
Underlying implementation:
public static String toString(int mod) { StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0) sb.append("public "); if ((mod & PROTECTED) != 0) sb.append("protected "); if ((mod & PRIVATE) != 0) sb.append("private "); /* Canonical order */ if ((mod & ABSTRACT) != 0) sb.append("abstract "); if ((mod & STATIC) != 0) sb.append("static "); if ((mod & FINAL) != 0) sb.append("final "); if ((mod & TRANSIENT) != 0) sb.append("transient "); if ((mod & VOLATILE) != 0) sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & NATIVE) != 0) sb.append("native "); if ((mod & STRICT) != 0) sb.append("strictfp "); if ((mod & INTERFACE) != 0) sb.append("interface "); if ((len = sb.length()) > 0) /* trim trailing space */ return sb.toString().substring(0, len-1); return ""; }
6.2: create reflection objects
public class Dog { @Override public String toString() { return "Dog{ puppy... }"; } } class Cat { @Override public String toString() { return "Cat{z kitten}"; } } class Test{ public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Scanner in = new Scanner(System.in); System.out.println("Enter the object you want to create"); String objMess = in.next(); Class<?> aClass = Class.forName("com.atguigu.reflect.start."+objMess); Object o = aClass.newInstance(); System.out.println("---->"+o); } }
6.3.1: get constructor (public private)
Get all public modifier constructors
Constructor<?>[] constructors = aClass.getConstructors();
Get all constructors of this class Contains non-public
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
Person person = personClass.newInstance(); The parameterless constructor is called by default
@Test public void test02() throws NoSuchMethodException { //1. Get Class Person person = new Person(); Class<? extends Person> aClass = person.getClass(); //2. Get all public modified constructors Constructor<?>[] constructors = aClass.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor); } System.out.println("--------------------declaredConstructors--------------------"); //Get all constructors of this class that contain non-public Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors(); for (Constructor<?> d : declaredConstructors) { System.out.println("d = " + d); } } @Test public void test01() throws IllegalAccessException, InstantiationException { //1. Get runtime type Class aClass = Person.class; //Creating objects with a parameterless constructor Object o = aClass.newInstance(); System.out.println("o = " + o); }
6.3.2: get the specified constructor
getDeclaredConstructor(String.class, int.class)
The parameter is a deformable parameter and can be passed in multiple. The data type is Class
Gets the specified constructor based on the formal parameter list passed in
@Test public void test02() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<Person> personClass = Person.class; Constructor<Person> constructor = personClass.getDeclaredConstructor(String.class, int.class); Person libai = constructor.newInstance("Li Bai", 20); System.out.println("libai = " + libai); } @Test public void test01() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1: Gets the class of the runtime Class<Person> personClass = Person.class; Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class); Person libai = declaredConstructor.newInstance("Li Bai"); System.out.println("libai = " + libai); }
6.4: get all attributes and operations by reflection:
personClass.getFields() Get all public properties of this class and its parent class
personClass.getDeclaredFields() Get all properties in this class (excluding those in the parent class), including non-public
General fixing steps:
1> You must first obtain the instance object of the class;
2> Operation public property:
2.1: getField("name") gets the name of the attribute and returns it to generate a Field attribute object
2.2: Field attribute object. Set (object, value);
3> Operation private properties:
3.1: getField("name") gets the name of the property and returns it to generate a Field property object
3.2: Field property object. setAccessible(true);
3.3: Field property object. Set (object, value);
4> Operation private static attribute: (static attribute belongs to class and does not need object)
4.1: getField("name") gets the name of the property and returns it to generate a Field property object
4.2: Field property object. setAccessible(true);
4.3: Field property object. set(null, value);
4.4: acquisition of static attributes Field property object. get(null)
@Test public void test03() throws IllegalAccessException, InstantiationException, NoSuchFieldException { //Operation static properties //Operation private static properties //Because static properties belong to class operations, objects are not required Class<Person> personClass = Person.class; //Get the instance object of a class first //Person person = personClass.newInstance(); //Get property object Field num = personClass.getDeclaredField("num"); num.setAccessible(true); num.set(null,1000); //Get property value property object. get() Object o = num.get(null); System.out.println("o = " + o); System.out.println("person = " + person); } @Test public void test02() throws IllegalAccessException, InstantiationException, NoSuchFieldException { //Operation private properties Class<Person> personClass = Person.class; //Get the instance object of a class first Person person = personClass.newInstance(); //At this time, the name attribute object is obtained Field salary = personClass.getDeclaredField("salary"); salary.setAccessible(true); salary.set(person,1230.09); System.out.println("person = " + person); } //Action public property @Test public void test01() throws NoSuchFieldException, IllegalAccessException, InstantiationException { Class<Person> personClass = Person.class; //Get the instance object of a class first Person person = personClass.newInstance(); //At this time, the name attribute object is obtained Field name = personClass.getField("name"); //set the attribute value of the object person in the way of the attribute object. set name.set(person,"libai"); System.out.println("person = " + person); }
6.5: get all methods in this class
public class Person extends Object { public void show() { System.out.println("this is show()"); } public void show(int a, double b) { System.out.println("this is show(int a,double b) " + a + "---> " + b); } private String show(String str) { System.out.println("this is show(String) ---> " + str); return str + "666"; } private static int sum(int a, int b) { { System.out.println("Static methods execute....."); return a + b; } } }
public class MethodTest { @Test public void test01(){ //Get all methods in this class Class<Person> personClass = Person.class; Method[] declaredMethods = personClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println("declaredMethod = " + declaredMethod); } } @Test public void test02(){ //Get all public methods of this class and its parent class Class<Person> personClass = Person.class; Method[] methods = personClass.getMethods(); for (Method method : methods) System.out.println("method = " + method); } @Test public void test03() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { //Operation public parameterless method Class<Person> personClass = Person.class; //The getMethod() Method returns a Method object Method show = personClass.getMethod("show"); //create object Person person = personClass.newInstance(); //Create object before operation Object invoke = show.invoke(person); } @Test public void test04() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { //Operation public parameterized method Class<Person> personClass = Person.class; //create object Person person = personClass.newInstance(); //The getMethod() Method returns a Method object Method show = personClass.getMethod("show", int.class, double.class); show.invoke(person,100,203.333); } @Test public void test05() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { //Operation private parameterized method Class<Person> personClass = Person.class; //create object Person person = personClass.newInstance(); //The getMethod() Method returns a Method object Method show = personClass.getDeclaredMethod("show", String.class); show.setAccessible(true); Object libai = show.invoke(person, "Li Bai"); System.out.println("libai = " + libai); } @Test public void test06() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //Operation private static parameterized method Class<Person> personClass = Person.class; //create object // Person person = personClass.newInstance(); //Get method object Method sum = personClass.getDeclaredMethod("sum", int.class, int.class); sum.setAccessible(true); //Static methods do not require objects Object invoke = sum.invoke(null, 10, 20); System.out.println("invoke = " + invoke); } }
6.6: use reflection to break through the limitations of generics
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ArrayList<String> list = new ArrayList<>(); list.add("Li Bai"); //Add 100 to the collection using reflection //Get list runtime class Class<? extends ArrayList> aClass = list.getClass(); //Call the add method of the list Method add = aClass.getMethod("add", Object.class); Object invoke = add.invoke(list, 100); System.out.println("invoke = " + invoke); System.out.println(list); }
6.7: reflection operation internal class:
public class TestInner { @Test public void test04() { //Gets the runtime class object of the inner class A of the Person class Class<Person.A> aClass = Person.A.class; //Gets the runtime type of the external class Class<?> declaringClass = aClass.getDeclaringClass(); System.out.println("declaringClass = " + declaringClass); } @Test public void test03() { Class<Person> aClass = Person.class; //public Class<?> Getdeclarangclass(): if the class object represents // If the class or interface of is an internal class or internal interface, its external class or external interface is returned; otherwise, null is returned. Class<?> declaringClass = aClass.getDeclaringClass(); System.out.println("declaringClass = " + declaringClass); } @Test public void test02(){ Class<Person> aClass = Person.class; //Get all inner classes of this class Class<?>[] declaredClasses = aClass.getDeclaredClasses(); for (Class<?> declaredClass : declaredClasses) { System.out.println("declaredClass = " + declaredClass); } } @Test public void test01(){ Class<Person> personClass = Person.class; //Gets this class and the public inner class inherited from the parent class Class<?>[] classes = personClass.getClasses(); for (Class<?> aClass : classes) { System.out.println("aClass = " + aClass); } } }
6.8: reflection operation array:
An Array class is also provided under the java.lang.reflect package. The Array object can represent all arrays.
The Array class provides the following methods:
Public static object newinstance (class <? > componenttype, int... Dimensions): creates a new array with the specified component type and dimension.
public static void setXxx(Object array,int index,xxx value): modify the value of the [index] element in the array to value. Xxx here corresponds to 8 basic data types. If the type of this attribute is a reference data type, the set(Object array,int index, Object value) method is directly used.
public static xxx getXxx(Object array,int index,xxx value): returns the value of the [index] element in the array. Xxx here corresponds to 8 basic data types. If the type of this attribute is a reference data type, you can directly use the get(Object array,int index) method.
@Test public void test010(){ //Is an array of String type with length of 6 Object instance = Array.newInstance(String.class, 6); // instance[0] = "Li Bai"; //Assign a value to an array Array.set(instance,0,"libai"); Array.set(instance,1,"Du Fu"); //Get value Object o = Array.get(instance, 1); System.out.println("o = " + o); }
6.8: Reflection reading annotation information:
Meta annotation:
Target: Specifies the location of the annotation
Retention: the lifecycle of an annotation
If you want annotations to be read using reflection, @ Retention(RetentionPolicy.RUNTIME)
@MyAnno("login") public class Person { @MyAnno String name; @MyAnno public void show(){ } } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE}) public @interface MyAnno { String value() default "hello"; } @Test public void test01(){ Class<Person> personClass = Person.class; //Gets the specified annotation MyAnno myAnno = personClass.getDeclaredAnnotation(MyAnno.class); String value = myAnno.value(); System.out.println("value = " + value); }