Java learning route (23) - reflection mechanism

1. Overview
(1) What is reflection: reflection refers to any Class class, and all components can be directly obtained at "runtime".
(2) Dynamically obtainable objects: Constructor object - Constructor, member variable object - Field, member method object - Method.
(3) Reflection key: The first step is to get the compiled Class object, and then you can get all the components of the Class.


2. Acquisition of reflection-related objects
(1) Acquisition of Class objects

//过程:Hello.java -> javac -> Hello.class
Class c = Hello.class;

1. Object.forName(String className) -> source code phase acquisition
2. Object.class -> memory phase acquisition
3. Object.class() -> instantiation phase acquisition

public class getClassInfoDemo {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            /*forName(类全名)*/
            Class c = Class.forName("com.zengoo.reflected.Student");
            System.out.println(c);
        } catch (ClassNotFoundException e) {
    
    
            throw new RuntimeException(e);
        }

        /*类获取*/
        System.out.println(Student.class);

        /*对象获取*/
        System.out.println(new Student().getClass());
    }
}

class Student{
    
    
    private String id;
    private String name;

    public Student() {
    
    
    }

    public Student(String id, String name) {
    
    
        this.id = id;
        this.name = name;
    }

    public String getId() {
    
    
        return id;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

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

    @Override
    public String toString() {
    
    
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

/*打印输出*/
class com.zengoo.reflected.Student
class com.zengoo.reflected.Student
class com.zengoo.reflected.Student

(2) Get the constructor

1. Related APIs

method illustrate
Constructor<?>[] getConstructors() Get all constructor objects modified by public
Constructor<?>[] getDecalaredConstructors() Get all constructor objects
Constructor<?> getConstructor(Class<T>… parameterTypes) Returns a single public constructor based on parameter types
Constructor<?> getDecalaredConstructor(Class<T>… parameterTypes) Get a single constructor object based on the parameter type

2. Get the constructor example

public class getClassConstructorDemo {
    
    
    public static void main(String[] args) {
    
    

        Class c = Student.class;

        //获取所有public构造器
        Constructor[] c1 = c.getConstructors();
        System.out.println("=============获取所有public构造器=============");
        for (Constructor constructor :c1) {
    
    
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }
        //获取所有构造器
        System.out.println("=============获取所有构造器=============");
        Constructor[] c2 = c.getDeclaredConstructors();
        for (Constructor constructor :c2) {
    
    
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }

        //获取单个public构造器对象
        System.out.println("=============获取单个public构造器对象=============");
        try {
    
    
            Constructor c3 = c.getConstructor();
            System.out.println(c3.getName() + "===>" + c3.getParameterCount());
        } catch (NoSuchMethodException e) {
    
    
            throw new RuntimeException(e);
        }

        //获取单个构造器对象
        System.out.println("=============获取单个构造器对象=============");
        try {
    
    
            Constructor c4 = c.getDeclaredConstructor(String.class,String.class);
            System.out.println(c4.getName() + "===>" + c4.getParameterCount());
        } catch (NoSuchMethodException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

/*打印输出*/
=============获取所有public构造器=============
com.zengoo.reflected.Student===>0
com.zengoo.reflected.Student===>2
=============获取所有构造器=============
com.zengoo.reflected.Student===>0
com.zengoo.reflected.Student===>2
=============获取单个public构造器对象=============
com.zengoo.reflected.Student===>0
=============获取单个构造器对象=============
com.zengoo.reflected.Student===>2

3. Get the constructor and call it

(1) Function: The function of obtaining the constructor is to initialize an object and return it.
(2) Related APIs

method illustrate
T newInstance(Object initargs) Create an object according to the specified constructor
void setAccessible(boolean flag) Setting true means ignoring access restrictions and violent reflection

(3) Example of use

class useConstructor{
    
    
    public static void main(String[] args) throws Exception {
    
    
        Constructor constructor = Student.class.getConstructor(String.class,String.class);
        constructor.setAccessible(true); //暴力破解私有权限,若构造器为公开权限,则不需要
        Student student = (Student) constructor.newInstance(UUID.randomUUID().toString(),"金牙齿");
        System.out.println(student);
    }
}

/*打印输出*/
Student{
    
    id='77430b37-a65f-4379-b181-437dc5544032', name='金牙齿'}

(3) Get member variables

1. Related APIs

method illustrate
Field<?>[] getFields() Get all member variables of public modification
Field<?>[] getDeclaredFields() Get all member variables
Field<?> getField(String name) Returns a single public member variable based on the parameter name
Field<?> getDecalaredField(String name) Returns a single member variable based on the parameter name
void set(Object obj,Object value) Inject a member variable data into the object
Object get(Object obj) Returns a single member variable based on the parameter name
void setAccessible(boolean b) Violence to open permissions
Class getType() Get the type of the attribute and return the Class object
String getName() get attribute name

2. Example of use

public class getClassFieldDemo {
    
    
    public static void main(String[] args) throws NoSuchFieldException {
    
    
        Class c = Student.class;

        //获取所有public成员变量
        Field[] fields = c.getFields();
        for (Field f :fields) {
    
    
            System.out.println(f.getType() + " " + f.getName());
        }

        //获取所有成员变量
        Field[] fields1 = c.getDeclaredFields();
        for (Field f :fields1) {
    
    
            System.out.println(f.getType() + " " + f.getName());
        }

        //获取单个public成员变量
        Field field = c.getDeclaredField("name");
        System.out.println(field.getType() + " " + field.getName());

        //获取单个成员变量
        Field field1 = c.getDeclaredField("id");
        System.out.println(field1.getType() + " " + field1.getName());
    }
}

/*打印变量*/
class java.lang.String id
class java.lang.String name
class java.lang.String name
class java.lang.String id

class useField{
    
    
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    
    
        Class c = Student.class;

        Field id = c.getDeclaredField("id");
        Field name = c.getDeclaredField("name");

        id.setAccessible(true);
        name.setAccessible(true);

        Student s = new Student();
        id.set(s, UUID.randomUUID().toString());
        name.set(s, "金钟罩");

        System.out.println(id.getType() + " " + id.get(s));
        System.out.println(name.getType() + " " + name.get(s));
    }
}

/*打印输出*/
class java.lang.String d368bc5c-76c9-413a-ad2d-565729b7afe9
class java.lang.String 金钟罩

(4) Obtain member method

1. Related APIs

method illustrate
Method[] getMethods() Returns an array of all public modified member method objects
Method[] getDeclaredMethods() Returns an array of all member method objects
Method getMethod(String name,Class<?>… parameterTypes) According to the method name and parameter list attributes, return a single public modified member method object
Method getDecalaredField(String name,Class<?>… parameterTypes) According to the method name and parameter list attributes, return a single modified member method object
void setAccessible(boolean b) Violence to open permissions

2. Example of use

public class getClassMethodDemo {
    
    
    public static void main(String[] args) throws NoSuchMethodException {
    
    
        Class c = Student.class;


        //获取所有public成员方法
        Method[] methods = c.getMethods();
        for (Method method :methods) {
    
    
            System.out.println(method.getGenericParameterTypes().toString() + " " + method.getName());
        }

        //获取所有成员方法
        Method[] methods1 = c.getDeclaredMethods();
        for (Method method :methods1) {
    
    
            System.out.println(method.getGenericParameterTypes().toString() + " " + method.getName());
        }

        //获取单个public成员变量
        Method method = c.getMethod("getName");
        System.out.println(method.getGenericParameterTypes().toString() + " " + method.getName());

        //获取单个成员变量
        Method method1 = c.getMethod("setId", String.class);
        System.out.println(method1.getGenericParameterTypes().toString() + " " + method1.getName());
    }
}

/*打印输出*/
[Ljava.lang.Class;@67b64c45 getName
[Ljava.lang.Class;@68837a77 toString
[Ljava.lang.Class;@6be46e8f setName
[Ljava.lang.Class;@3567135c getId
[Ljava.lang.Class;@327471b5 setId
[Ljava.lang.Class;@4157f54e wait
[Ljava.lang.Class;@90f6bfd wait
[Ljava.lang.Class;@47f6473 wait
[Ljava.lang.Class;@15975490 equals
[Ljava.lang.Class;@6b143ee9 hashCode
[Ljava.lang.reflect.Type;@9f70c54 getClass
[Ljava.lang.Class;@234bef66 notify
[Ljava.lang.Class;@737996a0 notifyAll
[Ljava.lang.Class;@61dc03ce getName
[Ljava.lang.Class;@50f8360d toString
[Ljava.lang.Class;@2cb4c3ab setName
[Ljava.lang.Class;@13c78c0b getId
[Ljava.lang.Class;@12843fce setId
[Ljava.lang.Class;@3dd3bcd getName
[Ljava.lang.Class;@97e1986 setId

3. Method call

class useMethod{
    
    
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    
    
        Class c = Student.class;
        Constructor constructor = c.getConstructor(String.class,String.class);
        constructor.setAccessible(true);

        Student student = (Student) constructor.newInstance(UUID.randomUUID().toString(),"金环法");

        System.out.println(student);

        Method method = c.getMethod("setName", String.class);

        method.setAccessible(true);
        method.invoke(student,"新名称");

        System.out.println(student);
    }
}

/*打印输出*/
Student{
    
    id='d001810b-88e7-468d-bb8c-bc4129970191', name='金环法'}
Student{
    
    id='d001810b-88e7-468d-bb8c-bc4129970191', name='新名称'}


3. The role of reflection

(1) Bypassing the compilation stage to add data to the collection (the principle is generic erasure, that is, mandatory execution)

class useClassDemo{
    
    
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    
    
        List<Integer> list1 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();

        list1.add(1);
        list1.add(2);
        list1.add(3);

        list2.add(1);
        list2.add(2);
        list2.add(3);

        System.out.println(list1.getClass());
        System.out.println(list2.getClass());

        System.out.println(list1.getClass() == list2.getClass());

        System.out.println("===========================");

        Class c = list2.getClass();

        Method method = c.getMethod("add", Object.class);

        method.invoke(list2,"字符串");

        System.out.println(list1.getClass() == list2.getClass());
        System.out.println(list1);
        System.out.println(list2);
    }
}

/*打印输出*/
class java.util.ArrayList
class java.util.ArrayList
true
===========================
true
[1, 2, 3]
[1, 2, 3, 字符串]

(2) The underlying principles of the general framework (emphasis)

Example of a generic framework using reflection

/**
* 需求:给定任意对象,在不清楚对象字段的情况下,将对象的字段名和对应值存储到文件中去。
*/

public class useReflectedToFrame {
    
    
    public static void main(String[] args) {
    
    
      Shop shop = new Shop(UUID.randomUUID().toString(),"店名","xxx市xxx区xxx街道xxx");
      Goods goods = new Goods(UUID.randomUUID().toString(),"商品名",28.5);

      String parentPath = "D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\outDir\\";

      TestUtil.save(shop,parentPath+"shop.txt");
      TestUtil.save(goods,parentPath+"goods.txt");
      System.out.println("打印完毕");
    }
}

/*自定义通用框架*/
class TestUtil{
    
    
    public static void save(Object obj,String pathname) {
    
    
        try(PrintStream printStream = new PrintStream(new FileOutputStream(pathname))){
    
    
            //1、提取对象的所有成员变量
            Class c = obj.getClass();

            Field[] fields = c.getDeclaredFields();
            for (Field field:fields) {
    
    
                field.setAccessible(true);
                //2、获取变量名
                String name = field.getName();
                //3、获取变量名对应的值
                String value = " = " + field.get(obj);

                printStream.println(name + value);
            }
        } catch (IllegalAccessException | FileNotFoundException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

class Shop{
    
    
    private String id;
    private String shopName;
    private String address;

    public Shop() {
    
    
    }

    public Shop(String id, String shopName, String address) {
    
    
        this.id = id;
        this.shopName = shopName;
        this.address = address;
    }

    public String getId() {
    
    
        return id;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public String getShopName() {
    
    
        return shopName;
    }

    public void setShopName(String shopName) {
    
    
        this.shopName = shopName;
    }

    public String getAddress() {
    
    
        return address;
    }

    public void setAddress(String address) {
    
    
        this.address = address;
    }

    @Override
    public String toString() {
    
    
        return "Shop{" +
                "id='" + id + '\'' +
                ", shopName='" + shopName + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

class Goods{
    
    
    private String id;
    private String goodsName;
    private double price;

    public Goods() {
    
    
    }

    public Goods(String id, String goodsName, double price) {
    
    
        this.id = id;
        this.goodsName = goodsName;
        this.price = price;
    }

    public String getId() {
    
    
        return id;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public String getGoodsName() {
    
    
        return goodsName;
    }

    public void setGoodsName(String goodsName) {
    
    
        this.goodsName = goodsName;
    }

    public double getPrice() {
    
    
        return price;
    }

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


    @Override
    public String toString() {
    
    
        return "Goods{" +
                "id='" + id + '\'' +
                ", goodsName='" + goodsName + '\'' +
                ", price=" + price +
                '}';
    }
}

shop.txt

id = cd23f6eb-91c3-4f19-adf5-654ef4602b2e
shopName = 店名
address = xxx市xxx区xxx街道xxx

goods.txt

id = 77d46cea-04ec-45dd-b806-f39179bfa37e
goodsName = 商品名
price = 28.5

Guess you like

Origin blog.csdn.net/Zain_horse/article/details/131054773