JAVA反射机制

Posted 技术很low的瓜贼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA反射机制相关的知识,希望对你有一定的参考价值。

文章目录

JAVA反射机制

一、概念:

  • 反射机制:创建对象与创建方法通过运行时传递的参数来决定,该机制叫做动态编程技术
  • 反射机制就是用于动态创建对象并且动态调用方法的机制
  • 绝大多数框架底层都为反射机制

二、Class类

1.概念

  • java.lang.Class类的实例可以用于描述Java应用程序中的类和接口,也就是一种数据类型
  • 该类没有公共构造方法,该类的实例由java虚拟机和类加载器自动构造完成,本质上就是加载到内存中的运行时类

2.获取Class对象的方式

  1. 使用数据类型.class的方式可以获取对应类型的Class对象
// 方式一:使用数据类型.class的方式可以获取对应类型的Class对象
        Class c1 = String.class;
        System.out.println(c1); // 调用类的toString方法打印   class java.lang.String
        c1 = int.class;
        System.out.println(c1); // int
        c1 = void.class;
        System.out.println(c1); // void
  1. 使用引用/对象.getClass()的方式可以获取对应类型的Class对象
// 方式二:使用引用/对象.getClass()的方式可以获取对应类型的Class对象
        String str = "tbtbtbtb";
        Class c2 = str.getClass();
        System.out.println(c2);
        Integer i = 500;
        c2 = i.getClass();
        System.out.println(c2);
  1. 使用包装类.TYPE的方式可以获取对应基本数据类型的Class对象
// 方式三:使用包装类.TYPE的方式可以获取对应基本数据类型的Class对象
        Class c3 = Integer.TYPE;
        System.out.println(c3); // 获取到的为基本数据类型,不是包装类
  1. 使用Class.forName()的方式来获取参数指定类型的Class对象
// 方式四:使用Class.forName()的方式来获取参数指定类型的Class对象(掌握)
        //Class c4 = Class.forName("String"); // 不能获取基本数据类型的Class对象,并且需要写全
        Class c4= Class.forName("java.lang.String");
        System.out.println(c4);
        c4 = Class.forName("java.util.Date");
        System.out.println(c4);
  1. 使用类加载器ClassLoader的方式获取指定类型的Class对象
// 使方式五:用类加载器ClassLoader的方式获取指定类型的Class对象
        ClassLoader classLoader = ClassTest.class.getClassLoader();
        // c1 = classLoader.loadClass("String");   错误
        Class c5 = classLoader.loadClass("java.lang.String");
        System.out.println(c5);
        c5 = classLoader.loadClass("java.lang.Integer");
        System.out.println(c5);
        c5 = classLoader.loadClass("java.util.Date");
        System.out.println(c5);

3.常用方法

方法功能
static Class<?> forName(String className)用于获取参数指定类型对应的Class对象并返回
T newInstance()用于创建该Class对象所表示类的新实例
Constructor getConstructor(Class<?>… parameterTypes)用于获取此Class对象所表示类型中参数指定的公共构造方法
Constructor<?>[] getConstructors()用于获取此Class对象所表示类型中所有的公共构造方法
Field getDeclaredField(String name)用于获取此Class对象所表示类中参数指定的单个成员变量信息
Field[] getDeclaredFields()用于获取此Class对象所表示类中所有成员变量信息
Method getMethod(String name, Class<?>… parameterTypes)用于获取该Class对象表示类中名字为name参数为 parameterTypes的指定公共成员方法
Method[] getMethods()用于获取该Class对象表示类中所有公共成员方法
		/**
         * 无参方式构造
         */
        System.out.println("--------反射机制创建对象并打印-------------");
        Class c1 = Class.forName("反射机制.constructor.Person");
        System.out.println(c1.newInstance());

        System.out.println("--------反射机制+读取配置文件方式创建对象并打印-------------");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("g:/a.txt")));
        String s = br.readLine();
        Class c2 = Class.forName(s);
        System.out.println(c2.newInstance());
        br.close();

三、Constructor类

1.概念:

  • java.lang.reflect.Constructor类主要用于描述获取到的构造方法信息

2.常用方法

方法功能
T newInstance(Object…initargs)使用此Constructor对象描述的构造方法来构造Class对象代表类型的新实例
int getModifiers()获取方法的访问修饰符
String getName()获取方法的名称
Class<?>[] getParameterTypes()获取方法所有参数的类型
/**
         * 有参方式构造
         */
        Constructor constructor1 = c2.getConstructor(String.class, String.class);
        Object o1 = constructor1.newInstance("yandongmu", "212222");
        System.out.println(o1);

        // 用于获取此Class对象所表示类型中所有的公共构造方法
        System.out.println("==============Constructor类的常用方法");
        Constructor[] constructors = c2.getConstructors();
        for (Constructor constructor2 : constructors) 
            System.out.println("获取到的方法的访问修饰符是" + constructor2.getModifiers());
            System.out.println("获取到的方法的名称是" + constructor2.getName());

            Class[] parameterTypes = constructor2.getParameterTypes();
            for (Class parameterType : parameterTypes) 
                System.out.print("获取到的类型是" + parameterType);
            
        

四、Field类

1.概念

  • java.lang.reflect.Field类主要用于描述获取到的单个成员变量信息

2.常用方法

方法功能
Object get(Object obj)获取参数对象obj中此Field对象所表示成员变量的数值
void set(Object obj, Object value)将参数对象obj中此Field对象表示成员变量的数值修改为参数value的数值
void setAccessible(boolean flag)当实参传递true时,则反射对象在使用时应该取消 Java 语言访问检查
int getModifiers()获取成员变量的访问修饰符
Class<?> getType()获取成员变量的数据类型
String getName()获取成员变量的名称
public class PersonFieldTest 

    public static void main(String[] args) throws Exception 
        /**
         * 通过反射机制来构造对象,以及获取成员变量的数值
         */

        // 1.获取Class对象
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("g:/a.txt")));
        String s = br.readLine();
        Class c = Class.forName(s);
        // 2.根据Class对象获取对应的有参构造方法
        Constructor constructor = c.getConstructor(String.class, String.class);
        // 3.使用有参构造方法来获取Person类型的对象
        Object obj = constructor.newInstance("tb", "22");
        // 4.根据Class对象获取对应的成员变量的信息
        Field field = c.getDeclaredField("name");
        // 反射对象在访问时取消java语言访问检查 意味着成员变量的访问修饰符是private也可以被访问
        field.setAccessible(true);
        // 5.使用对象来获取成员变量的数值
        Object o = field.get(obj);
        System.out.println("获取到成员变量信息为" + o);
        // 修改成员变量的数值
        field.set(obj, "浩旺");
        System.out.println("修改后获取到成员变量信息为" + field.get(obj));

        // 获取一个类中所有的成员变量
        Field[] declaredFields = c.getDeclaredFields();
        for (Field declaredField : declaredFields) 
            System.out.println("获取到的成员变量的访问修饰符是" + declaredField.getModifiers());
            System.out.println("获取到的成员变量的数据类型是" + declaredField.getType())
            
            System.out.println("获取到的成员变量的名称是" + declaredField.getName());
        
    

五、Method类

1.概念

  • java.lang.reflect.Method类主要用于描述获取到的单个成员方法信息

2.常用方法

方法功能
Object invoke(Object obj, Object… args)使用对象obj来调用此Method对象所表示的成员方法,实参传递args
int getModifiers()获取方法的访问修饰符
Class<?> getReturnType()获取方法的返回值类型
String getName()获取方法的名称
Class<?>[] getParameterTypes()获取方法所有参数的类型
Class<?>[] getExceptionTypes()获取方法的异常信息
public class PersonMethodTest 

    public static void main(String[] args) throws Exception 
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("g:/a.txt")));
        String s = br.readLine();
        Class c = Class.forName(s);
        Constructor constructor = c.getConstructor(String.class, String.class);
        Object obj = constructor.newInstance("tb", "2121");
        Method method = c.getMethod("getName");
        System.out.println("调用方法后的返回结果为" + method.invoke(obj));

        // 获取所有的成员方法及其详细信息
        Method[] methods = c.getMethods();
        for (Method method1 : methods) 
            System.out.println("获取到的成员变量的访问修饰符是" + method1.getModifiers());
            System.out.println("获取到的成员变量的返回值类型是" + method1.getReturnType());
            System.out.println("获取到的成员方法的名称是" + method1.getName());
            Class<?>[] parameterTypes = method1.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) 
                System.out.print(parameterType);
            
            Class<?>[] exceptionTypes = method1.getExceptionTypes();
            for (Class<?> exceptionType : exceptionTypes) 
                System.out.println(exceptionType);
            
        

    

六、获取其他信息方法

方法功能
Package getPackage()获取所在的包信息
Class<? super T> getSuperclass()获取继承的父类信息
Class<?>[] getInterfaces()获取实现的所有接口
Annotation[] getAnnotations()获取注解信息
Type[] getGenericInterfaces()获取泛型信息

以上是关于JAVA反射机制的主要内容,如果未能解决你的问题,请参考以下文章

java 中反射机制和内省机制的区别是啥?

请问java中的反射机制与用法

java反射机制

如何利用java的反射机制动态创建对象

java的反射机制

Java反射机制详解