Home >Java >javaTutorial >reflection mechanism in java

reflection mechanism in java

伊谢尔伦
伊谢尔伦Original
2016-11-30 09:47:011320browse

The reflection mechanism of java is one of the characteristics of java. The reflection mechanism is the basis for building framework technology. Using reflection can make the program more flexible and avoid hard-coding the program in the code. Compared with many beginners who have only been exposed to the basics of Java, reflection is still a very hazy and difficult concept to understand. Let's talk about some applications of reflection.

The Java reflection mechanism refers to the function of dynamically obtaining information and dynamically calling object methods in the running state. Java reflection has three dynamic properties: 1. Generating object instances at runtime, 2. Calling and issuing during runtime, 3. Changing attributes at runtime.

So what is the principle of reflection? Then we must first take a look at the execution process of the java program. If you want the java program to run, the java class must be loaded by the java virtual machine. When running a program, the required classes are already loaded during compilation. I have to mention it here. I believe many people don’t have a clear concept of what is compile time and what is run time. Compile time is when the compiler helps you translate the code into code that the device can recognize. That is to say, compilation The compiler will do some simple work during compilation, such as checking whether there are any errors in your syntax, whether there are errors in writing keywords or names, and loading classes. These are all things that need to be done during compilation. So what does it do during runtime? ? Runtime is when your program starts. After the code is loaded into the memory, it is runtime. Runtime inspection is to perform operations and judgments in your memory. Let’s give a small example:

 int[] nums = new int[3];
        nums[4] = 12;

Obviously, the above This code will cause an array subscript out-of-bounds error. However, the program does not report an error when compiling. Instead, an ArrayIndexOutOfBoundsException error will be reported when running. This is the difference between compilation and runtime.

And Java’s reflection mechanism is not sure which class is loaded when compiling. It is loaded and used when the program is running. Let’s use a simple picture to look at the execution process of reflection:

reflection mechanism in java

The Java reflection mechanism can know the basic structure of a class. This ability to detect the structure of a Java class becomes "self-examination." The automatic prompt function when we use software such as eclipse to write code uses the principle of Java reflection. So what functions can we achieve through Java's reflection? 1. Determine the class to which any object belongs at run time, 2. Construct an object of any class at run time, 3. Determine the properties and methods of any class at run time, 4. Call any object at run time method. Commonly used classes in Java reflection include the Class class: the core class of reflection. Through the Class class, you can obtain the attributes, methods, etc. of the class. Filed class: represents the attributes of the class, and can get and set the values ​​of the attributes in the class. Method class: represents the method of the class, which can be used to obtain information about the methods in the class, or to execute methods. Constructor class: Represents the constructor method of the class.

Okay, we have learned some basic information about java reflection. Now we will use code to implement each function of reflection one by one:

The first one is also the simplest one. First of all, we must use the Class class. Instantiate it first, but the Class class has no constructor, so how do we instantiate it? There are three ways to create a Class class:

public static void main(String[] args) { //第一种方法,通过对象.getClass()方法 User user = new User();
        Class<? extends User> cs = user.getClass();
        System.out.println(cs); //第二种方法,通过类名.class Class<User> cs1 = User.class;
        System.out.println(cs1); //第三种方法,通过Class本身的forName()方法,注意forName()方法会抛出一样,并且里面的参数需要完整的包名和类名 Class<?> cs2 = null; try {
            cs2 = Class.forName("cn.fanfu.demo.User");
        } catch (ClassNotFoundException e) { // TODO Auto-generated catch block  e.printStackTrace();
        }
        System.out.println(cs2);
    }

The third forName() method can be instantiated when the class is uncertain Class, more flexibility.

The second is to create a new instance of the Class class object through the parameterized construction of the Class class:

public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, 
InstantiationException, IllegalAccessException, InvocationTargetException { 
//在这里为了更直观的展示,直接使用String类 Class<?> cs =Class.forName("java.lang.String"); char[] ch = {&#39;大&#39;,&#39;家&#39;,&#39;好&#39;,&#39;!&#39;,&#39;!&#39;}; 
//调用Class类的有参构造函数,函数里的值为类.class Constructor<?> cst = cs.getConstructor(char[].class);
       String name = (String) cst.newInstance(ch);
       System.out.println(name); //因为这里的异常会使代码没有直观的显示,所以我直接抛给虚拟机 }

The third is to obtain a series of elements such as the class's structure, interface, methods, properties, etc.:

public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException { //先创建好两个对象 Class<?> cs = Class.forName("cn.fanfu.demo.User");
        Constructor<?>[] con = null; //通过getConstructors()方法返回一个Constructor[]数组,数组里存储的是该类的各个构造 con = cs.getConstructors(); for (Constructor<?> item : con) {
            System.out.println(item);
        } //通过getInterfaces()方法返回一个Class<?>[]数组,数组里存储的是该类的各个接口 Class<?>[] inter = cs.getInterfaces(); for (Class<?> item : inter) {
            System.out.println(item);
        } //通过getSuperclass()方法返回一个Class<?> Class<?> parent = cs.getSuperclass(); //java中只支持单继承,所以只有一个父类  System.out.println(parent); //通过getMethods()方法返回一个Method[]数组,数组里存储的是该类的各个方法 Method[] method = cs.getMethods(); for (Method item : method) {
            System.out.println(item);
        } //通过getDeclaredFields()方法返回一个Field[]数组,数组里存储的是该类的各个属性 Field[] fiel = cs.getDeclaredFields(); for (Field item : fiel) {
            System.out.println(item);
        } //getDeclaredFields()方法可以获取全部属性,getFields()方法只能获取到公有属性 Field[] fiel1 = cs.getFields(); for (Field item : fiel1) {
            System.out.println(item);
        }
    }

The fourth is Get or modify the value of the attribute of the class:

public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException, NoSuchFieldException { //创建User对象 User us = new User();
        us.setAge(12);
        us.setName("张三");
        Class<?> cs = us.getClass(); //获取私有属性的值 Field fl = cs.getDeclaredField("name"); //要先设置允许访问 fl.setAccessible(true); //通过get方法指定对象获取值 String name = (String) fl.get(us);
        System.out.println(name); //通过set方法指定对象并修改值 fl.set(us, "李四");
        String name2 = (String) fl.get(us);
        System.out.println(name2);        
    }

The fifth is to call the method through reflection:

public static void main(String[] args) throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            InstantiationException, IllegalAccessException,
            InvocationTargetException, NoSuchFieldException { //创建User对象 User us = new User();
        us.setAge(12);
        us.setName("张三");
        Class<?> cs = us.getClass(); //通过getMethod()方法获取类中方法,该方法有两个参数,一个指定方法名,一个指定方法中参数的类型 Method mm = cs.getMethod("say"); //通过invoke()方法调用方法,该方法有两个参数,一个指定对象,另一个传递参数  mm.invoke(us);
    }


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn