When the program is running, the program structure or variable type is allowed to change. This language is called a dynamic language. We believe that Java is not a dynamic language, but it has a very prominent dynamic related mechanism, commonly known as: reflection.
It is said in the IT industry that without reflection there would be no framework. The existing frameworks are all based on reflection. In actual project development, frameworks are used the most, and classes are filled in the most. The concept of reflection is the mediator that combines frameworks and classes. Therefore, reflection is the stepping stone to contact project development!
What is the reflection mechanism?
The reflection mechanism is in the running state. For any class, it can know all the attributes and properties of the class. Method; for any object, any of its methods and properties can be called; this dynamically obtained information and the function of dynamically calling the object's methods are called the reflection mechanism of the Java language.
What the reflection mechanism can do
The reflection mechanism mainly provides the following functions:
Determine the class to which any object belongs at run time;
Construct an object of any class at run time;
Determine the member variables and methods of any class at run time;
Call the method of any object at run time;
Generate dynamic proxy.
Specific function implementation
1. The reflection mechanism has three methods to obtain the class. Let’s get the Employee type
//第一种方式: Classc1 = Class.forName("Employee"); //第二种方式: //java中每个类型都有class 属性. Classc2 = Employee.class; //第三种方式: //java语言中任何一个java对象都有getClass 方法 Employeee = new Employee(); Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
2 , Create an object: After getting the class, we create its object, using newInstance:
Class c =Class.forName("Employee"); //创建此Class 对象所表示的类的一个新实例 Objecto = c.newInstance(); //调用了Employee的无参数构造方法.
3. Get attributes: Divided into all attributes and specified attributes:
Let’s first look at getting all How to write attributes:
//获取整个类 Class c = Class.forName("java.lang.Integer"); //获取所有的属性? Field[] fs = c.getDeclaredFields(); //定义可变长的字符串,用来存储属性 StringBuffer sb = new StringBuffer(); //通过追加的方法,将每个属性拼接到此字符串中 //最外边的public定义 sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n"); //里边的每一个属性 for(Field field:fs){ sb.append("\t");//空格 sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等 sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字 sb.append(field.getName()+";\n");//属性的名字+回车 } sb.append("}"); System.out.println(sb);
Get specific attributes and learn by comparing them with traditional methods:
public static void main(String[] args) throws Exception{ <span style="white-space:pre"> </span>//以前的方式: /* User u = new User(); u.age = 12; //set System.out.println(u.age); //get */ //获取类 Class c = Class.forName("User"); //获取id属性 Field idF = c.getDeclaredField("id"); //实例化这个类赋给o Object o = c.newInstance(); //打破封装 idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。 //给o对象的id属性赋值"110" idF.set(o, "110"); //set //get System.out.println(idF.get(o)); }
Method reflection
Class class has the simplest method, getName():
public class Demo2 { public static void main(String[] args) { Class c1 = int.class;//int 的类类型 Class c2 = String.class;//String类的类类型 Class c3 = void.class; System.out.println(c1.getName()); System.out.println(c2.getName()); System.out.println(c2.getSimpleName()); System.out.println(c3.getName()); } }
The getName method can print out the class name of this class type. We can also use the getSimpleName() method to print out the class name that does not include the package name. The name of the class. As can be seen from the above code, basic data types and void keywords all exist in class types.
Case:
public class ClassUtil { public static void printClassMethodMessage(Object obj){ //要获取类的信息》》首先我们要获取类的类类型 Class c = obj.getClass(); //我们知道Object类是一切类的父类,所以我们传递的是哪个子类的对象,c就是该子类的类类型。 //接下来我们要获取类的名称System.out.println("类的名称是:"+c.getName()); /* *我们知道,万事万物都是对象,方法也是对象,是谁的对象呢? * 在java里面,方法是Method类的对象 *一个成员方法就是一个Method的对象,那么Method就封装了对这个成员 *方法的操作 *///如果我们要获得所有的方法,可以用getMethods()方法,这个方法获取的是所有的Public的函数,包括父类继承而来的。如果我们要获取所有该类自己声明的方法,就可以用getDeclaredMethods()方法,这个方法是不问访问权限的。 Method[] ms = c.getMethods();//c.getDeclaredMethods() //接下来我们拿到这些方法之后干什么?我们就可以获取这些方法的信息,比如方法的名字。 //首先我们要循环遍历这些方法 for(int i = 0; i < ms.length;i++){ //然后可以得到方法的返回值类型的类类型 Class returnType = ms[i].getReturnType(); //得到方法的返回值类型的名字 System.out.print(returnType.getName()+" "); //得到方法的名称 System.out.print(ms[i].getName()+"("); //获取参数类型--->得到的是参数列表的类型的类类型 Class[] paramTypes = ms[i].getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } } }
Summary idea:
Get the name of the class through method reflection Steps:
1. Get the class type of the class
2. Through the class Type method to get the class (getMethods())
3. Loop through the obtained methods
4. Get the class type of the return value type through getReturnType() of these methods, and get the return value through the class type Type name
5.getName() gets the name of the method, getParameterTypes() gets the class type of the parameter type in this method.
Reflection of member variables
First we need to realize that member variables are also objects and are java.lang.reflect .Field class object, that is to say, the Field class encapsulates the operations on member variables. Since it encapsulates member variables, how do we obtain these member variables? It has such a method:
public class ClassUtil { public static void printFieldMessage(Object obj){ Class c = obj.getClass(); //Field[] fs = c.getFields(); }
The getFields() method here obtains the information of all public member variables. And the public member variables in the reflection of the method also have information about all self-declared member variables:
Field[] fs = c.getDeclaredFields();
After we get it, we can traverse (since the Field information is encapsulated, then we You can get the Field type)
for (Field field : fs) { //得到成员变量的类型的类类型 Class fieldType = field.getType(); String typeName = fieldType.getName(); //得到成员变量的名称 String fieldName = field.getName(); System.out.println(typeName+" "+fieldName); }
Constructor reflection
Whether it is method reflection, member variable reflection, or constructor reflection, we only need to know: To obtain class information, you must first obtain the class type of the class.
public static void printConMessage(Object obj){Class c = obj.getClass(); /* * 首先构造函数也是对象,是java.lang.Constructor类的对象 * 也就是java.lang. Constructor中封装了构造函数的信息 * 和前面说到的一样,它也有两个方法: * getConstructors()方法获取所有的public的构造函数 * getDeclaredConstructors()方法得到所有的自己声明的构造函数 */ //Constructor[] cs = c.getConstructors(); Constructor[] cs = c.getDeclaredConstructors(); for (Constructor constructor : cs) { //我们知道构造方法是没有返回值类型的,但是我们可以: System.out.print(constructor.getName()+"("); //获取构造函数的参数列表》》得到的是参数列表的类类型 Class[] paramTypes = constructor.getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName()+","); } System.out.println(")"); } }