Reflection overview
Reflection is that for any Class, you can directly get all the components of this Class "at run time".
At runtime, you can directly get the Constructor object of this class: Constructor
At runtime, you can directly get the member variable object of this class: Field
At runtime, you can directly get the member Method object of this class: Method
This ability of dynamically obtaining class information and dynamically calling components in classes at runtime is called the reflection mechanism of Java language.
The key of reflection mechanism: the first step of reflection is to get the compiled Class object first, and then you can get all the components of Class.
HelloWorld.java -> javac -> HelloWorld.class Class c = HelloWorld.class;
In essence, it is Class file is a class object.
The basic function of reflection: get the bytecode file object of the class at run time, and then parse all the components in the class.
The core idea and key of reflection is to get the compiled class file object.
class structure in memory
Reflection get class object
The first step of reflection is to get the object of Class
Method 1: Class C1 = class Forname ("full class name");
Method 2: Class c2 = class name class
Method 3: Class c3 = object getClass();
@Test public void test1() { Student student1 = new Student(); Student student2 = new Student(); // The first method is to get class objects Class<?> s1 = null; try { s1 = Class.forName("Student"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // The second method is to obtain class objects Class<Student> s2 = Student.class; // The third method is to obtain class objects Class<? extends Student> s3 = student1.getClass(); System.out.println(s1); System.out.println(s2); System.out.println(s3); }
Reflection get constructor object
Get the constructor object using reflection technology and use
API
@Test public void test2() throws NoSuchMethodException { Class<Student> sc = Student.class; // 1. Get all the constructors Constructor<?>[] constructors = sc.getDeclaredConstructors(); // Name of output constructor + number of parameters for (Constructor<?> constructor : constructors) { System.out.println(constructor.getName() + " Number of parameters:" + constructor.getParameterCount() + "individual"); } // 2. Get a single constructor Constructor<Student> constructor = sc.getDeclaredConstructor(String.class, String.class); System.out.println(constructor.getName() + "Number of parameters:" + constructor.getParameterCount()); }
Obtain the constructor object using reflection technology and create an object using the obtained content
The function of the constructor after reflection is still to create an object. If the constructor is public, you can directly create a new object. If the constructor is private, you need to violently reflect the constructor in advance and then construct the object.
Reflection can directly replace encapsulation, and private reflection can also be executed.
// 3. Create an object using a parameterless constructor Student o = (Student)constructors[0].newInstance(); System.out.println(o); // 4. Create objects using full parameter constructors constructor.setAccessible(true); // Violent reflex Student student = constructor.newInstance("Sun WuKong", "20"); System.out.println(student.getName() + student.getAge());
Get member variable object by reflection
The parameter is a variable name
During the assignment operation, you need to select which object is first, and then give it the value to be assigned. When obtaining the value, you need to find the value of which object to obtain first.
// Assign a value to the member variable name Student student = new Student(); // First, we need to new out an object, so that the paper can know which member variable of which object is assigned a value field.setAccessible(true); field.set(student,"Qi Tian Da Sheng"); System.out.println(student.getName()); String name= (String) field.get(student); System.out.println(name);
Here you can also use the way of violent reflection.
Reflection get method object
@Test public void test5() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class<Student> sc = Student.class; Method[] methods = sc.getDeclaredMethods(); for (Method method : methods) { String name = method.getName(); System.out.println(name); } Method eat = sc.getDeclaredMethod("eat", String.class); Student student = new Student(); Object invoke = eat.invoke(student, "puppy"); System.out.println(invoke); Method eat1 = sc.getDeclaredMethod("eat", String.class,String.class); Object invoke1 = eat1.invoke(student, "puppy", "Eat delicious food"); System.out.println(invoke1); }
Bypassing the compilation phase to add data to the collection
Reflection is a technology that works at runtime. At this time, the generics of the collection will not produce constraints. At this time, other elements of any type can be stored for the collection
Generics can only restrict the collection to operate certain data types in the compilation stage. When compiling into a Class file and entering the running stage, its real type is ArrayList, and generics are equivalent to being erased.
You can get the class class through the object, find the add method, and then call the add method.
@Test public void test6() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ArrayList<String> list = new ArrayList<>(); list.add("lala"); System.out.println(list); Class aClass = list.getClass(); Method add = aClass.getDeclaredMethod("add", Object.class); add.invoke(list,1); System.out.println(list); }
Reflection as a general framework
Requirement: for any object, if you don't know the object field, you can store the field name and corresponding value of the object in the file.
Define a method that can receive objects of any class.
Every time you receive an object, you need to resolve the names of all member variables of the object.
This object may be arbitrary, so how can we know the names of all member variables of this object?
Use reflection to get the Class object of the object, and then get all member variable information.
Traverse the member variable information, and then extract the specific value of the member variable in the object
Save the member variable name and value into the file.