反射概述和功能介绍

反射的简介

反射的概念

反射,框架设计的灵魂,是将类中各个组成部分封装为其它对象,这就是反射机制

反射的好处

  1. 可以在程序运行过程中操作这些对象。
  2. 解耦,来提高程序的可扩展性。

反射获取字节码Class对象的三种方法

  1. Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象。该方法多用于配置文件,将类名定义在配置文件中。读取文件,加载类。
  2. 类名.class:通过类名的属性类获取。 多用于参数的传递。
  3. 对象.getClass():getClass()方法在Object类中定义的,返回一个Class对象。故所有类都有这个方法。多用于对象获取字节码的方式。
  • 注: 1. 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个。2. 不同的字节码文件对应的class类对象均不相同。

Class对象获取功能概述

获取成员变量的方法

Field[] getFields():获取所有public修饰的成员变量。
Field[] getField(String name):获取指定名称的public修饰的成员变量。
Field[] getDeclaredFields():获取所有的成员变量,不受修饰符的影响。
Field getDeclaredFields(String name):获取指定名称的成员变量,不受修饰符的影响。

代码示例1

package Reflect.reflect;
import Reflect.domain.Person;
import java.lang.reflect.Field;
public class exmple01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.获取Class对象
        Class personClass = Person.class;
        /*
             - Field[] getFields():获取所有public修饰的成员变量。
             - Field[] getField(String name):获取指定名称的public修饰的成员变量
         */
        //2.获取Person里的成员变量
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
    
    //打印
            System.out.println(field);
        }
        System.out.println("-------------------");
        //3.获取Person中指定的成员变量
        Field a = personClass.getField("a");
        System.out.println(a);
        System.out.println("-------------------");
        //4. 获取成员变量中的值
        Person p = new Person();
        System.out.println( a.get(p));
        System.out.println("-------------------");
        //5. 设置成员变量中的值
        a.set(p, "张三");
        System.out.println(p);
        System.out.println("=====================分隔线===================");
        /*
            - Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
            - Field getDeclaredFields(String name):获取指定的成员变量,不考虑修饰符
         */
        //获取所有的成员变量
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
    
    
            System.out.println(declaredField);
        }
        System.out.println("-------------------");
        //获取指定的成员变量
        Field d = personClass.getDeclaredField("d");
        d.setAccessible(true);//暴力反射
        Object value = d.get(p);
        System.out.println(value);

    }

}

获取构造方法

(构造方法的特点:类名和方法名得相同,区别在于构造方法的参数不同)
Constructor<?>[] getConstructors()
Constructor< T > getConstructor(类<?>…parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor< T > getDeclaredConstructor(类<?>…parameterTypes)
注:其主要作用和获取成员变量的方法类似。

代码示例2

package Reflect.reflect;

import Reflect.domain.Person;

import java.lang.reflect.Constructor;

public class exmple02{
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.获取Class对象
        Class personClass = Person.class;
        /*
            Constructor<T>  getConstructor(类<?>...parameterTypes)
         */
        //有参构造
        Constructor constructor = personClass.getConstructor(String.class, int.class);
        System.out.println(constructor);
        //创建对象
        Object obj = constructor.newInstance("张三", 23);
        System.out.println(obj);
        System.out.println("---------------------------------------------");
        //获取无参构造
        Constructor constructor1 = personClass.getConstructor();
        System.out.println(constructor);
        //创建对象
        Object obj1 = constructor1.newInstance();
        System.out.println(obj1);
        System.out.println("---------------------------------------------");
        //在获取无参构造创建对象的时候,可以使用Class类中的newInstance()
        Object o = personClass.newInstance();
        System.out.println(o);

    }

}

获取成员方法

Method[] getMethods()
Method getMethod(String name,类<?>… parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,类<?>… parameterTypes)
注:其主要作用和获取成员变量的方法类似。

代码示例3

package Reflect.reflect;

import Reflect.domain.Person;

import java.lang.reflect.Method;

public class exmple03{
    
    
    public static void main(String[] args)throws Exception {
    
    
        Class personClass = Person.class;
        //获取指定名称的无参方法
        Method eat_method = personClass.getMethod("eat");
        Person p = new Person();
        //执行方法
        eat_method.invoke(p);

        //获取指定名称的有参方法
        Method eat_method2 = personClass.getMethod("eat", String.class);
        eat_method2.invoke(p, "小鸡炖蘑菇");

        //获取所以public修饰的方法
        Method[] method = personClass.getMethods();
        for (Method method1 : method) {
    
    

            System.out.println(method1);
            //获取所有方法名
            System.out.println(method1.getName());
        }
    }
}

获取类名

String getName()

代码示例4

package Reflect.reflect;

import Reflect.domain.Person;
 
  public class example05 {
    
    
    public static void main(String[] args){
    
    
    	//获取class对象
        Class personClass = Person.class;
         //获取类名
        String name = personClass.getName();
        //打印
        System.out.println(name);
     }
  }

注意事项

私有的不能直接被访问到值,访问的话会报错Exception in thread “main” java.lang.IllegalAccessException;故需要在访问时,忽略访问权限修饰符的安全检查,采用暴力反射的方式,具体如上代码示例1。

各个组成部分功能介绍

Field:成员变量

操作:

  1. 设置值:Object get(Object obj),需要传对象
  2. 获取值:set(Object obj, Object value)

Constructor:构造方法

作用:

  1. 创建对象:T newInstance(Object… initargs).
  2. 如果使用空参数构造方法创建对象,操作可以简化:使用Class对象中的newInstance().

Method :方法对象

作用:

  1. 执行方法:Object invoke()
  2. 获取方法名称:String getName()

结语

以上为本人自己在学习期间所做的笔记,若有错误欢迎大家指正!

猜你喜欢

转载自blog.csdn.net/weixin_51012090/article/details/119077504
今日推荐