• Java 基础——反射机制


    什么是反射

    在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    Class类

    获取Class对象的方式:

    1. 调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。例如:
      MyObject x;
      Class c1 = x.getClass();

    2. 使用Class类的中静态forName()方法获得与字符串对应的Class对象。例如:
      Class c2=Class.forName(“类名或接口名”);

    3. 如果T是一个Java类型,那么T.class就代表了匹配的类对象。例如:
      Class cl1 = Manager.class;
      Class cl2 = int.class;
      Class cl3 = Double[].class;

    4. 通过类加载器获取类对象,例如:
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      Class cl1 = loader.loadClass("类名");

    Class类的重要方法如下:

    1. 获取类名
      • String getName()
    2. 获取Class对象
      • static Class<?> forName(String className)
    3. 获取类加载器
      • ClassLoader getClassLoader()
    4. 创建类的实例
      • T newInstance()
    5. 获取反射类对象
      1. 获取构造函数反射类
        • Constructor getConstructor(Class<?>... parameterTypes)
        • Constructor<?>[] getConstructors()
        • Constructor getDeclaredConstructor(Class<?>... parameterTypes)
        • Constructor<?>[] getDeclaredConstructors()
      2. 获取类方法的反射类
        • Method getMethod(String name, Class<?>... parameterTypes)
        • Method[] getMethods()
        • Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        • Method[] getDeclaredMethods()
      3. 获取类成员变量的反射类
        • Field getField(String name)
        • Field[] getFields()
        • Field getDeclaredField(String name)
        • Field[] getDeclaredFields()
    • 注意:getXXX()和getDeclaredXXX()的区别是,getXXX()只能获取public的反射类对象,getDeclaredXXX()则没有限制。

    反射类

    反射类通过Class类对象来获取,主要包括构造函数、成员变量、类方法,通过反射类对象可以实例化目标类、调用目标类对象的方法、操作目标类对象的域。

    1. java.lang.reflect.Constructor
      使用newInstance()方法实例化目标类,注意Class类的newInstance()方法只能调用默认无参构造函数,使用Constructor的newInstance()方法可以带参。
      • T newInstance(Object... initargs)
    2. java.lang.reflect.Method
      Method对象最重要的方法就是invoke(),相当于调用实例的方法:
      • Object invoke(Object obj, Object... args)
    3. java.lang.reflect.Field
      Field方法最主要的方法是set():
      • void set(Object obj, Object value)
      • void setXXX(Object obj, XXX z)

    一个例子

    https://github.com/kaname233/SpringLearn/tree/master/src/top/sunjing98/reflect
    一个普通的Java类Student:

    展开查看 ```java package top.sunjing98.reflect; public class Student { private String stuName; private int stuAge;
    public Student() {
    }
    
    public Student(String stuName, int stuAge) {
        this.stuName = stuName;
        this.stuAge = stuAge;
    }
    
    public void introduce() {
        System.out.println("stuName: " + stuName + " stuAge: " + stuAge);
    }
    
    public String getStuName() {
        return stuName;
    }
    
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }
    
    public int getStuAge() {
        return stuAge;
    }
    
    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }
    

    }

    </details>
    通过反射机制创建并操作目标类对象:
    ```java
    package top.sunjing98.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    public class ReflectTest {
        public static Student initByDefaultConst() throws Throwable {
            //1、通过类装载器获取类对象
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            Class clazz = loader.loadClass("top.sunjing98.reflect.Student");
            //2、通过类对象获取构造器对象,通过构造器对象实例化类
            Constructor constructor = clazz.getDeclaredConstructor( null);
            Student s = (Student) constructor.newInstance();
            //3、通过类对象获取方法对象,通过反射方法设置属性
            Method setStuName = clazz.getMethod("setStuName", String.class);
            Method setStuAge = clazz.getMethod("setStuAge", int.class);
            setStuName.invoke(s, "张三");
            setStuAge.invoke(s, 23);
            return s;
        }
    
        public static void main(String[] args) throws Throwable {
            Student s = initByDefaultConst();
            s.introduce();
        }
    }
    

    输出:

    stuName: 张三 stuAge: 23
    

    作者:lykxbg —— 来一块小饼干

    出处:http://www.cnblogs.com/lykxbg/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    C#——Unity事件监听器
    关于RAS加解密的工具类
    关于Map的源码分析之HashMap
    关于Map的源码分析
    关于Set的源码分析
    关于集合List的源码分析
    关于String源码分析
    hdu 1285 确定比赛名次
    hdu 2553 N皇后问题
    hdu 1312 Red and Black
  • 原文地址:https://www.cnblogs.com/lykxbg/p/11810765.html
Copyright © 2020-2023  润新知