Java reflection-step by step, java reflection
What is reflection?
Reflection (Reflection) means that the Java program can dynamically obtain the internal information of all classes in the program during runtime, and can dynamically call the Internal Attributes and methods of any object.
Why reflection?
Why do we need reflection? This is mainly determined by the dynamic nature of reflection. Because reflection can be used to dynamically create objects, this gives a lot of java flexibility, this reduces the coupling of program calls, makes the system more flexible, and can better cope with changes.
Reflection Application
Run reflection. We can do the following:
Determine the class to which any object belongs at runtime
Construct any class object at runtime
Judge the member variables and methods of any class at runtime
Call the member variables and methods of any object at runtime.
Generate dynamic proxy
Common Reflection-related classes include:
Java. lang. Class: represents a Class
Java. lang. reflect. Method: indicates the Method of the class.
Java. lang. reflect. Field: represents the member variable of the class.
Java. lang. reflect. Constructor: indicates the class Constructor.
Class
The Class is the source of the reflection mechanism. In fact, the so-called reflection indicates that the Class name is obtained through object reflection from the running result of the program.
Reflection is actually a reverse process used in a normal way, just like reflection in physics:
Through reflection, we can get the information: the attributes, methods, constructors, and classes of A Class implement what interfaces and parent classes are. For each Class, JRE retains an unchanged Class Object for it. A Class object contains information about a specific Class.
The Class itself is also a Class. Each Class has only one Class instance in the JVM, and each Class Object corresponds to one loaded to the JVM. class file, each Class instance will remember which class instance generated by itself.
Class objects are obtained through reflection in four ways.
Now we have a established class Person with the class path package com. tgb. reflect. common;
1. The specific Person class is known and obtained through the class attribute of the Person class. This method is the most secure and reliable, and has the highest program performance.
@Testpublic void test1(){Classclass1 = Person.class;System.out.println(class1);}
2. For an instance of the known Person Class, call the getClass () method of the instance to obtain the Class object.
@Testpublic void test2() {Personp = new Person();Classclass1 =p.getClass();System.out.println(class1);}
3. It is known that the full Class Name of the Person Class is in the Class path and can be obtained through the static method forName () of the Class.
@Testpublic void test3()throws ClassNotFoundException{StringclassName = "com.tgb.reflect.common.Person";Classclass1 = Class.forName(className);System.out.println(class1);}
4. Get the Class object through the Class loader.
@Testpublic void test4()throws ClassNotFoundException{StringclassName= "com.tgb.reflect.common.Person";ClassLoaderclassLoader =this.getClass().getClassLoader();Classclass1=classLoader.loadClass(className);System.out.println(class1);}
The code of the Class object obtained in the above four methods has the same result, and the running result is "classcom. tgb. reflect. common. Person ";
Class Loader
When a Program actively uses a class, if the class has not been loaded into the memory, the system will initialize the class through the following three steps.
ClassLoader (Class Loader) is used to put the class (. class) installed in the memory, the JVM will generate an initialization loader hierarchy consisting of three class loaders at runtime, as shown in:
Let's look at the Code:
@ Testpublic void test1 () throws ClassNotFoundException {// 1. obtain a system class loader ClassLoaderloader1 = ClassLoader. getSystemClassLoader (); System. out. println ("system Class Loader:" + loader1); // 2. obtain the parent class loader of the System class loader, that is, the extension class loader ClassLoaderloader2 = loader1.getParent (); System. out. println ("extended Class Loader:" + loader2); // 3. obtain the parent class loader of the extended class loader, that is, the bootstrap Class Loader ClassLoaderloader3 = loader2.getParent (); System. out. println ("bootstrap loader:" + loader3); // 4. test the class loader that loads the current class. Classclass1 = Person. class; ClassLoaderloader4 = class1.getClassLoader (); System. out. println ("current Class Loader:" + loader4); // 5. test which class loader loads StringclassName = "java. lang. string "; Classclass2 = Class. forName (className); ClassLoaderloader5 = class2.getClassLoader (); System. out. println ("JDK-provided String class loader:" + loader5 );}
The running result is:
System Class Loader: sun. misc. Launcher $ AppClassLoader @ 60e53b93
Extension Class Loader: sun. misc. Launcher $ ExtClassLoader @ 5acf9800
Bootstrap loader: null
The class loader of the current class: sun. misc. Launcher $ AppClassLoader @ 60e53b93
String class loader provided by JDK: null
The code running result shows that, the classes we define ourselves are loaded by the system class loaders. the upper level of the system class loaders is the extension class loaders, and the upper level of the extension class loaders are not allowed to be obtained by the system, however, the upper level of the expansion class loader is indeed the bootstrap class loader, which is mainly used to load the class library that comes with jvm.
The class loader can be used to read the configuration files in the system. Here is a simple example. the properties file is placed in our class directory. We use the class loader to read the content.
The content of our configuration file is very simple:
User = root
Password = 123456
The Code is as follows:
@ Testpublic void test2 () throws IOException {// obtain classloader ClassLoaderclassLoader = this. getClass (). getClassLoader (); // use the class loader to read the property file to the input stream StringfilePath = "com \ tgb \ reflect \ test1 \ Test. properties "; InputStreaminputStream = ClassLoader. getSystemResourceAsStream (filePath); // get the file content Propertiesproperties = new Properties (); properties. load (inputStream); Stringuser = properties. getProperty ("user"); System. out. println ("user:" + user); Stringpassword = properties. getProperty ("password"); System. out. println ("password:" + password );}
The running result is:
User: root
Password: 123456
Postscript
This article introduces the basic knowledge of reflection, as well as the source Class of reflection, describes four methods for getting Class objects, and introduces some knowledge about Class loaders, this article introduces reflection so much. Let's continue in the next article.