1.1 role of reflection mechanism
Bytecode files can be manipulated through the emission mechanism in the java language.
Code snippets can be manipulated through reflection mechanisms. (. class file).
1.2 principle of reflection mechanism:
1. First, a clear concept: everything is an object - classes are also objects
2. Then know the contents of the class: modifier constructor field method
3. Secondly, understand loading: when Animal.class is in the hard disk, it is a file. When it is loaded into memory, it can be regarded as an object, an object of java.lang.class
1.3 package of reflection mechanism related classes
java.lang.reflect.*;
1.4 important categories related to reflection mechanism
java.lang.Class represents the entire bytecode and represents a type (the entire class)
java.lang.reflect.Method represents method bytecode in bytecode (method in class)
java.lang.reflect.Constructor represents the construction method in bytecode (the construction method in class)
java.lang.reflect.Field represents the attribute bytecode in bytecode (member variable in class: static variable + instance variable)
1.5 there are three ways to obtain the bytecode of the whole class:
The first: Class c = Class.forName("full package name + class name");
The second type: Class c = object. getClass();
Third: Class c = any type. class;
public static void main(String[] args) { Class c1=null; Class c2=null; try { /* Method 1: class. forName(): the forName() method under class 1.Static method 2.The parameter of the method is a string, which needs to be a complete class name 3.The full class name must have a package name. The java.lang package cannot be omitted 4.Return Class object */ //Gets the bytecode file for the entire class c1=Class.forName("java.lang.String");//c1 represents String.class, or c1 represents String type c2=Class.forName("java.util.Date");//c2 stands for Date type Class c3=Class.forName("java.lang.Integer");//c3 stands for Integer type System.out.println(c1); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Method 2: any object in java has a method: getClass() String str="www"; Class x=str.getClass();//x represents the String.class bytecode file, and x represents the String type System.out.println(c1==x);//True (determines the memory address of the object) Date d=new Date(); Class dCl=d.getClass(); System.out.println(c2==dCl);//True (the memory addresses stored in C2 and dCl variables are the same, and both point to the bytecode file in the method area) // Method 3: any type in java language, including basic data type, has. class attribute Class a = String.class;//a stands for String type Class b = int.class;//b stands for int type Class c = double.class;//c stands for double type Class f = Date.class;//f stands for Date type System.out.println(x==a);//true }
Note: when the bytecode file is loaded into the JVM, only one copy is loaded.
one point six Application of reflection mechanism
1. The Class obtained through the reflection mechanism can call the parameterless construction method to instantiate the object
Instantiate the object through the newInstance() method of Class.
// c represents Date type Class c = Class.forName("java.util.Date"); // Instantiate an object of Date type Object obj = c.newInstance();
Note: the parameterless construct is actually called inside the newInstance() method. You must ensure that the parameterless construct exists, otherwise an "instantiation" exception will appear.
public class ReflectTest02 { public static void main(String[] args) { // Creating objects using construction methods User user=new User(); System.out.println(user); // Create objects using the reflection mechanism try { // The Class is obtained through the reflection mechanism, and the object is instantiated through the Class Class c = Class.forName("com.wanho.po.User");//c stands for User type // The newInstance() method calls the parameterless construction of the User class to complete the creation of the object. // Note: the newInstance() method calls a parameterless construct. Ensure that the parameterless construct exists. Object obj = c.newInstance(); System.out.println(obj);//com.wanho.po.User@6d06d69c } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2. Verify the flexibility of reflection mechanism
Write the java code again, and you can instantiate different objects without changing the java source code. Comply with OCP opening and closing principle: open to extension and close to modification.
public class ReflectTest03 { public static void main(String[] args) throws Exception { // Only one User class object can be created //User user = new User(); // Create different instantiated objects by modifying the configuration file // Read the classinfo.properties configuration file through the IO stream // Relative path under project / review/classinfo.properties FileReader reader = new FileReader("classinfo.properties"); // Create attribute class object Map Properties pro = new Properties();//Key and value are all String types // Load profile pro.load(reader); // Close flow reader.close(); // Get value through key String className = pro.getProperty("className"); System.out.println("Full package name+Class name:"+className); //Instantiate objects through reflection mechanism Class c = Class.forName(className); Object obj = c.newInstance(); System.out.println("Objects instantiated by reflection:"+obj); } }
3. If you only want the "static code block" of a class to execute, you can use Class.forName("full class name of the class")
Important: if you only want the static code block of a class to be executed, and no other code will be executed, you can use: Class.forName("full class name"); The execution of this method will lead to class loading. When the class is loaded, the static code block is executed.
public class ReflectTest04 { public static void main(String[] args) { try { //Class.forName() the execution of this method will cause: class loading Class.forName("com.wanho.reflect.MyClass"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public class MyClass { //Static code blocks are executed when the class is loaded and only once static { System.out.println("MyClass Class static code block executed!!!!"); } }
4. Research on file path problem
The following is a general way to get the absolute path of a file. The premise is that the file needs to be in the classpath (src) before it can be used.
public class AboutPath { public static void main(String[] args) throws Exception{ //The disadvantages of this method are: poor portability. The default current path is the root of the project //When the code leaves eclipse and goes to another location, the path is not the root of the project, and this path is invalid //FileReader reader = new FileReader("classinfo.properties"); //The following is a common path. Even if the code changes location, such writing is still common //Note: the premise of using the following general method is that this file must be in the classpath. //Under classpath: everything under src is under classpath. //src is the root path of the class /* Types of class loader: startup class loader, application class loader and extension class loader Thread.currentThread() Current thread object getContextClassLoader() Is the method of the thread object, which can get the classloader object of the current thread getResource() [Get resources] this is the method of the classloader object. The classloader of the current thread loads resources from the root path of the class by default */ //The following absolute paths to get files are common String path = Thread.currentThread().getContextClassLoader().getResource("classinfo2.properties").getPath(); //Using the above code, you can obtain the absolute path of a file. // /D:/software/eclipse-workspace/review/bin/classinfo2.properties System.out.println(path); // To get the path of db.properties file, you need to start from the root path of the class String path2 = Thread.currentThread().getContextClassLoader().getResource("com/wanho/po/db.properties").getPath(); System.out.println(path2); } }
5.IoProperties.java
Note: the classinfo2.properties configuration file is under the classpath (src)
public class IoPropertiesTest { public static void main(String[] args) throws Exception{ //Get the absolute path of a file ---- get the absolute path according to the relative path // String path = Thread.currentThread().getContextClassLoader().getResource("classinfo2.properties").getPath(); //System.out.println(path); // Read configuration file // FileReader reader = new FileReader(path); InputStream reader = Thread.currentThread().getContextClassLoader().getResourceAsStream("classinfo2.properties"); Properties pro = new Properties(); // Load profile pro.load(reader); reader.close(); // Get value according to key String className = pro.getProperty("className"); System.out.println(className); } }
6. Resource binder
A resource binder is provided under the java.util package to obtain the content in the property configuration file.
Note: when using this method, the property configuration file xxx.properties must be placed under the class path.
public class ResourceBundleTest { public static void main(String[] args) { // Resource binders can only bind xxx.properties files. And this file must be in the classpath. The file extension must also be properties // Note: when writing a path, the extension behind the path cannot be written. // ResourceBundle bundle = ResourceBundle.getBundle("classinfo2"); ResourceBundle bundle = ResourceBundle.getBundle("com/wanho/po/db"); // Get value according to key String className = bundle.getString("className"); System.out.println(className); } }
one point seven Reflection property Field(Field class)
1.7.1 get Field object
methodmeaninggetField(String name)Gets the property object of the specified public modifiergetFields()Get all property objects decorated with public in the class and return the property array Field []getDeclaredField(String name)Gets the specified property objectgetDeclaredFields()Get all property objects and return the property array Field []getModifiers()Gets the modifier list of the attribute. The returned modifier is an int number, and each number is the modifier codeModifier.toString(int i)Converts the modifier code to a String and returns the String typegetType()Gets the type of the attribute and returns the Class objectpublic class ReflectTest05 { public static void main(String[] args) throws Exception{ // Get the entire class Class studentClass = Class.forName("com.wanho.po.Student"); System.out.println("studentClass:"+studentClass); // Get class name String className = studentClass.getName(); System.out.println("Full class name:"+className); String simpleName = studentClass.getSimpleName(); System.out.println("Simple class name:"+simpleName); System.out.println("================"); // Get all the public decorated properties in the class Field[] fields = studentClass.getFields(); System.out.println(fields.length); // Fetch attribute Field f = fields[0]; // Gets the name of the property String fieldName = f.getName(); System.out.println(fieldName); // Get all properties Field[] fields2 = studentClass.getDeclaredFields(); System.out.println(fields2.length); System.out.println("================"); // ergodic for(Field field:fields2) { // private java.lang.String com.wanho.po.Student.name System.out.println(field); // Gets the list of modifiers for the property int i = field.getModifiers(); //The returned modifier is a number, and each number is the code of the modifier! System.out.println(i); // Converts the modifier code to a string String modifierString = Modifier.toString(i); System.out.println("Property modifier:"+modifierString); // Gets the type of the property Class fieldType = field.getType(); //String fName = fieldType.getName(); //java.lang.String String fName = fieldType.getSimpleName(); //String System.out.println("Type of property:"+fName); // Gets the name of the property System.out.println("The name of the property:"+field.getName()); } } }
1.7.2 decompile Field
public class ReflectTest06 { public static void main(String[] args) throws Exception{ // Create this string to splice StringBuilder sBuilder = new StringBuilder(); // Get the entire class Class studentClass = Class.forName("com.wanho.po.Student"); sBuilder.append(Modifier.toString(studentClass.getModifiers())+" class "+studentClass.getSimpleName()+"{\n"); // Get all properties Field[] fields = studentClass.getDeclaredFields(); for(Field field:fields) { sBuilder.append("\t"); sBuilder.append(Modifier.toString(field.getModifiers())); sBuilder.append(" "); sBuilder.append(field.getType().getSimpleName()); sBuilder.append(" "); sBuilder.append(field.getName()); sBuilder.append(";\n"); } sBuilder.append("}"); System.out.println(sBuilder); } }
1.7.3 accessing object properties through reflection mechanism (key)
/** * (Master): access object properties through reflection mechanism * How to access the properties of a java object through reflection mechanism? * Assign a set to the property * get value of property */ public class ReflectTest07 { public static void main(String[] args) throws Exception{ //Access the properties of an object without using the reflection mechanism Student student = new Student(); student.no=1001;//Assign 1001 to the no attribute of the student object //Element 1: Student object; Element 2: no attribute; Element 3: attribute value 1001 // Read attribute value System.out.println(student.no); //Using reflection mechanism, how to access the properties of an object. (set get) // Get the entire class Class studentClass = Class.forName("com.wanho.po.Student"); Object obj = studentClass.newInstance();// Student object. (the bottom layer calls the parameterless construction method) // Get no attribute (get attribute according to attribute name) Field noField=studentClass.getDeclaredField("no"); // Assign values to attributes /* Although the reflection mechanism is used, three elements are indispensable: Element 1: obj object Element 2: no attribute Element 3: no attribute value 1002 */ noField.set(obj, 1002);//Assign 1002 to the no attribute of obj object (Student object) // Read the value of the property // Two elements: get the value of no attribute of obj object. System.out.println(noField.get(obj)); // Can I access private properties---- may not Field nameField=studentClass.getDeclaredField("name"); //System.out.println(nameField); // Breaking encapsulation (disadvantage of reflection mechanism: breaking encapsulation may leave opportunities for criminals!!!) // After this setting, private can also be accessed externally. nameField.setAccessible(true); // Assign a value to the name attribute nameField.set(obj, "marry"); // Gets the value of the name property System.out.println(nameField.get(obj)); } }
one point eight Reflection Method class (emphasis)
1.8.1 reflection Method
methodmeaninggetMethods()Get all public method objectsgetMethod(String name, Class... parameterTypes)Gets the method object of the specified publicgetDeclaredMethods()Get all Method objects and return Method []getDeclaredMethod(String name, Class... parameterTypes)Gets the specified method objectgetParameterTypes()Get the parameter list and return Class []public class ReflectTest08 { public static void main(String[] args) throws Exception{ // Get class Class uSClass = Class.forName("com.wanho.service.UserService"); // Get all methods Method[] methods = uSClass.getDeclaredMethods(); // ergodic for(Method method:methods) { // Get modifier list System.out.println(Modifier.toString(method.getModifiers())); // Gets the return value type of the method System.out.println(method.getReturnType().getSimpleName()); // Get method name System.out.println(method.getName()); // Get parameter list Class[] parameterTypes = method.getParameterTypes(); // ergodic for(Class parameterType:parameterTypes) { System.out.println(parameterType.getSimpleName()); } } } }
1.8.2 decompile Method
public class ReflectTest09 { public static void main(String[] args) throws Exception{ StringBuilder s = new StringBuilder(); // Get class Class uSClass = Class.forName("java.lang.String"); s.append(Modifier.toString(uSClass.getModifiers())+" class "+uSClass.getSimpleName()+"{\n"); Method[] methods = uSClass.getDeclaredMethods(); for(Method method:methods) { s.append("\t"); s.append(Modifier.toString(method.getModifiers())); s.append(" "); s.append(method.getReturnType().getSimpleName()); s.append(" "); s.append(method.getName()); s.append("("); Class[] parameterTypes = method.getParameterTypes(); // ergodic for(Class parameterType:parameterTypes) { s.append(parameterType.getSimpleName()); s.append(","); } s.deleteCharAt(s.length()-1); s.append(")"); s.append("{}\n"); } s.append("}"); System.out.println(s); } }
1.8.3 calling methods through reflection mechanism (key points)
invoke() Method in Method class
methodmeaninginvoke(Object obj, Object ...value)Call this method/** * ((emphasis) how to call an object's method through reflection mechanism * Five stars ※※※※※ * * The reflection mechanism makes the code universal, and the changeable contents are written to the configuration file, * By modifying the configuration file, you can create different objects and call different methods, * But the java code doesn't need to be changed. This is the charm of reflection mechanism. * @author Lucky * */ public class ReflectTest10 { public static void main(String[] args) throws Exception{ // How to call a method without using reflection mechanism //create object UserService userService = new UserService(); // Call method /* Element analysis: Element 1: userService object Element 2: login method name Element 3: argument list Element 4: return value */ boolean f= userService.login("admin", "123"); System.out.println(f); //userService.logout(); // Use reflection mechanism Class c = Class.forName("com.wanho.service.UserService"); // create object Object obj = c.newInstance(); // Get method object Method loginMethod = c.getDeclaredMethod("login", String.class,String.class); // Call method // Calling a method requires four elements. // One of the most important methods of reflection mechanism must be remembered. // Four elements /* loginMethod method obj object "admin","123"Actual parameters retValue Return value */ Object retValue = loginMethod.invoke(obj, "admin", "123");//Calling methods with invoke System.out.println(retValue); } }
one point nine Reflection Constructor
1.9.1 decompile Constructor
public class ReflectTest11 { public static void main(String[] args) throws Exception{ StringBuilder s = new StringBuilder(); Class vipClass = Class.forName("com.wanho.po.Vip"); // Gets the modifier of the class s.append(Modifier.toString(vipClass.getModifiers())); s.append(" class "); // Get class name s.append(vipClass.getSimpleName()); s.append("{\n"); // Splicing construction method Constructor[] constructors = vipClass.getDeclaredConstructors(); for(Constructor constructor : constructors) { s.append("\t"); // Gets the modifier of the constructor s.append(Modifier.toString(constructor.getModifiers())); s.append(" "); s.append(vipClass.getSimpleName()); s.append("("); // Splicing parameters Class[] parameterTypes = constructor.getParameterTypes(); for(Class parameterType : parameterTypes) { s.append(parameterType.getSimpleName()); s.append(","); } if(parameterTypes.length > 0) { // Deletes the string at the last subscript position s.deleteCharAt(s.length() - 1); } s.append("){}\n"); } s.append("}"); System.out.println(s); } }
1.9.2 calling construction method through reflection mechanism
public class ReflectTest12 { public static void main(String[] args) throws Exception{ // Create objects without reflection Vip vip = new Vip(); Vip vip2 = new Vip(1001, "marry", "1999", true); // Create objects using the reflection mechanism Class vipClass = Class.forName("com.wanho.po.Vip"); // Call parameterless construction Object obj = vipClass.newInstance(); System.out.println(obj); // Call parameterized constructor // 1. Get construction method Constructor con = vipClass.getDeclaredConstructor(int.class); // 2. Call the new object of the constructor Object obj2 = con.newInstance(1002); System.out.println(obj2); // Method for obtaining parameterless construction Constructor con2 = vipClass.getDeclaredConstructor(); Object obj3 = con2.newInstance(); System.out.println(obj3); } }
one point one zero Get parent class and parent interface through reflection
public class ReflectTest13 { public static void main(String[] args) throws Exception{ // Get String class Class stringClass = Class.forName("java.lang.String"); // Gets the parent class of the String class Class superClass = stringClass.getSuperclass(); System.out.println("String Parent class of:"+superClass.getName()); // Get all interfaces implemented by the String class (a class can implement multiple interfaces) Class[] interfaces = stringClass.getInterfaces(); for(Class inter : interfaces) { System.out.println("String Interface implemented by class:"+inter.getName()); } } }