java reflection application foundation, super detailed

Posted by Hurklefish on Thu, 17 Feb 2022 14:28:32 +0100

summary

Reflection is one of the features of Java programming language. It allows running Java programs to check themselves, or "self-examination", also known as "introspection". Reflection is so powerful that it can even directly manipulate the private properties of the program. We all have a concept in the previous study. Private classes can only be accessed internally, but not externally. However, this provision is completely broken by reflection.
Reflection is like a mirror. It can get all the information of a class at run time, get any defined information (including member variables, member methods, constructors, etc.), and manipulate the fields, methods, constructors, etc. of the class.


Fundamentals of reflection application

Basic test class

package com.cy;

import java.util.Objects;

public class Shop {
    public final Integer NUMBER = 10;
    public final String BRAND = "BRAND";
    private String name;
    private Integer price;
    private Integer sales;

    public Shop() {
        System.out.println("-----I am a public parameterless constructor-----");
    }

    private Shop(String name, Integer price) {
        System.out.println("-----I am a private parameter constructor-----");
        this.name = name;
        this.price = price;
    }

    public Shop(String name, Integer price, Integer sales) {
        System.out.println("-----I am a public parameter constructor-----");
        this.name = name;
        this.price = price;
        this.sales = sales;
    }

    private void priMethod() {
        System.out.println("-----I'm a private method-----");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Integer getSales() {
        return sales;
    }

    public void setSales(Integer sales) {
        this.sales = sales;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Shop shop = (Shop) o;
        return name.equals(shop.name) &&
                price.equals(shop.price) &&
                sales.equals(shop.sales);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, price, sales);
    }
    
	@Override
    public String toString() {
        return "Shop{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", sales=" + sales +
                '}';
    }
}

Get class object properties

Class.forName("classpath") – get class object
getPackage().getName() - get package name
getName() – get the full class name
getSimpleName() - class name, excluding package name

Test:

	@Test
    public void test1() throws Exception{
        Class c = Class.forName("com.cy.Shop");
        String packageName = c.getPackage().getName();
        String className = c.getName();
        String simpleName = c.getSimpleName();
        System.out.println("packageName: " + packageName);
        System.out.println("className: " + className);
        System.out.println("simpleName: " + simpleName);
    }

Operation results:

Get member variable definition information

getFields() – get all exposed member variables, including inherited variables
getDeclaredFields() – get the member variables defined by this class, including private variables and excluding inherited variables
Getfield (variable name) – gets the specified member variable
Getdeclaraedfield (variable name) – gets the member variable that specifies the definition of this class

Test:

	@Test
	public void test2() throws Exception{
	    Shop shop = new Shop();
	    Class c = shop.getClass();
	    Field[] fields = c.getFields();
	    for (Field field : fields) {
	        System.out.println(field.toString());
	    }
	    System.out.println("-----------------------------");
	    Field[] declaredFields = c.getDeclaredFields();
	    for (Field field : declaredFields) {
	        System.out.println(field.toString());
	    }
	    System.out.println("-----------------------------");
	    Field field = c.getField("NUMBER");
	    Field declaredField = c.getDeclaredField("name");
	    System.out.println(field.toString());
	    System.out.println(declaredField.toString());
	}

Operation results:

Get method definition information

getMethods() – get all visible methods, including inherited methods
getDeclaredMethods() – get the methods defined by this class, including private methods and excluding inherited methods
Getmethod (method name, parameter type list) – get the specified visible method
Getdeclaredmethod (method name, parameter type list) – get the methods specified by this class, including private and excluding inherited methods

Test:

	@Test
    public void test3() throws Exception{
        Class c = Class.forName("com.cy.Shop");
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            System.out.println(method.toString());
        }
        System.out.println("----------------------------");
        Method[] declaredMethods = c.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method.toString());
        }
        System.out.println("----------------------------");
        Method method = c.getMethod("setName", String.class);
        System.out.println(method.toString());
        Method declaredMethod = c.getDeclaredMethod("priMethod");
        System.out.println(declaredMethod.toString());
    }

Operation results:

Get construction method definition information

getConstructors() – get all exposed constructors
Getdeclaraedconstructors () – get all construction methods, including private ones
Getconstructor (list of parameter types) – gets the specified exposed constructor
Getdeclaraedconstructor (int.class, string. Class) – get the specified constructor, including private

Test:

	@Test
    public void test4() throws Exception{
        Class c = Class.forName("com.cy.Shop");
        Constructor[] constructors = c.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor.toString());
        }
        System.out.println("---------------------------------------");
        Constructor[] declaredConstructors = c.getDeclaredConstructors();
        for (Constructor constructor : declaredConstructors) {
            System.out.println(constructor.toString());
        }
        System.out.println("---------------------------------------");
        Constructor constructor = c.getConstructor();
        System.out.println(constructor.toString());
        Constructor declaredConstructor = c.getDeclaredConstructor(String.class, Integer.class);
        System.out.println(declaredConstructor.toString());
    }

Reflection access class properties

Reflect new instance

- execute parameterless construction when creating a new instance
Object obj = class newInstance();

- get construction method
Constructor t = class Getconstructor (parameter type list);

- create a new instance and execute the construction method
Object obj = t.newinstance (parameter data list);

Reflection call member variable

- get variables
Field = class Getdeclaraedfield (variable name);

- allow access to private members
field.setAccessible(true);

- assign values to variables
field. Set (instance, value);

- reflect the value of the access variable
Object v = field. Get (instance);

Reflection calls member methods

Acquisition method
Method m = class Getdeclaraedmethod (method name, parameter type list);

Allow private methods to be called
m.setAccessible(true)

Reflection lets the specified instance execute the method
Object returnValue = m.invoke (instance, parameter data)

Test:

	@Test
    public void test5() throws Exception{
        Class c = Class.forName("com.cy.Shop");
        Constructor declaredConstructor = c.getDeclaredConstructor(String.class, Integer.class);
        // Reflection allows access to private constructors
        declaredConstructor.setAccessible(true);
        // Reflection calls a private constructor to create an instance
        Shop shop = (Shop)declaredConstructor.newInstance("Apple", 10);
        System.out.println(shop.toString());
        System.out.println("-----------------------------------------");
        Constructor constructor = c.getConstructor();
        // Reflection calls the public constructor to create an instance
        Shop shop1 = (Shop)constructor.newInstance();
        System.out.println(shop1.toString());
        System.out.println("-----------------------------------------");
        Field field = c.getDeclaredField("name");
        // Reflection allows access to member variables
        field.setAccessible(true);
        // Assign values to member variables
        field.set(shop1, "Banana");
        // Reflection access member variable
        String name = (String)field.get(shop1);
        System.out.println(shop1.toString());
        System.out.println(name);
        System.out.println("-----------------------------------------");
        Method method = c.getDeclaredMethod("priMethod");
        // Reflection allows access to private methods
        method.setAccessible(true);
        // The private method is called by the specified instance of reflection
        method.invoke(shop1);
    }

Operation results:

Topics: Java Back-end reflection