20、反射:

20、反射:

反射概述:

什么是反射?

反射允许对封装类的字段,方法和构造函数的信息进行编程访问。(API中的描述)

翻译成人话:

反射允许对成员变量,成员方法,构造方法的信息进行编程访问。

反射可以将成员变量,成员方法,构造方法获取出来,再进行操作(比如IDEA中的提示功能,就是反射机制的体现)。


获取class对象的三种方式:

  1. Class.forName(“全类名”);——这样能获得该类的字节码文件对象
  2. 类名.class;
  3. 对象.getClass();——定义再Object类中

这三个对应Java中的三个阶段。

  1. 源代码阶段——使用Class.forName(“全类名”)
  2. 加载阶段——类名.class
  3. 运行阶段——对象.getClass()

什么叫全类名

就是包名加类名。在IDEA中可以快捷复制,在该类下选中类名右键,看到copy后有个copy reference选项,点击即可。

package com.jiangxian.reflect;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class MyReflect {
    public static void main(String[] args) throws ClassNotFoundException {
        // 第一种方式
        Class Clazz = Class.forName("com.jiangxian.reflect.Student");
        System.out.println(Clazz);

        // 第二种方式:
        System.out.println(Student.class); // 注意访问权限

        // 第三种方式:
        System.out.println(new Student().getClass());
    }
}

第一种方式最常用,第二种作为参数使用,第三种局限最大必须有对象。


Java中的一个重要思想

万物皆对象!


反射获取构造方法:

规则:

  • get表示获取;
  • Declared 表示私有;
  • 最后的 s 表示所有,为负数型式;
  • 若当前获取到的是私有的,必须要临时修改访问权限,否则无法使用。
方法名说明
Constructor<?>[] getConstructors()获得所有的构造(只能public修饰)
Constructor<?>[] getDeclaredConstructors()获得所有的构造(包含private修饰)
Constructor getConstructor(Class<?>… parameterTypes)获取指定构造(只能public修饰)
Constructor getDeclaredConstructor(Class<?>… parameterTypes)获取指定构造(包含private修饰)
package com.jiangxian.reflect;

import java.lang.reflect.Constructor;

/**
 * @author JiangXian~
 * @version 1.0
 */

public class MyReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        // 1.获取整体(class 字节码对象)
        Class clazz = Class.forName("com.jiangxian.reflect.Student");

        // 2. 获取构造器对象
        System.out.println("======获取public的=======");
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        //3. 获取所有构造器对象
        System.out.println("======获取所有的=======");
        Constructor[] constructors1 = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }

        //4. 获取指定参数的构造器
        System.out.println("======获取指定参数的构造器======");
        Constructor constructor01 = clazz.getConstructor();
        System.out.println(constructor01);
        Constructor constructor02 = clazz.getConstructor(String.class, int.class);
        System.out.println(constructor02);
        Constructor constructor03 = clazz.getDeclaredConstructor(String.class);
        System.out.println(constructor03);

    }
}

创建对象:

涉及到的方法:newInstance

package com.jiangxian.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author JiangXian~
 * @version 1.0
 */

public class Constructor_ {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class clazz = Class.forName("com.jiangxian.reflect.Student");

        // 创建无参的构造器
        Constructor con = clazz.getConstructor();
        Student stu1 = (Student)con.newInstance();
        System.out.println(stu1);

        // 创建有参构造器:
        Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
        Student stu2 = (Student)con2.newInstance("John", 1);
        System.out.println(stu2);

        // 暴力反射(跳过private的限制)
        Constructor con3 = clazz.getDeclaredConstructor(String.class);
        con3.setAccessible(true);
        Student stu3 = (Student)con3.newInstance("JiangXian");
        System.out.println(stu3);
    }

}



反射获取成员变量:

规则:

  • get 表示获取;
  • Declared 表示私有;
  • 最后的 s 表示所有,复数形式;
  • 若获取到的成员变量是私有型式,那么需要临时修改访问权限。
方法名说明
Field[] getFields()返回所有成员变量对象的数组(只能拿public的)
Field[] getDeclaredFields()返回所有成员变量对象的数组,存在就能拿到
Field getField(String name)返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name)返回单个成员变量对象,存在就能拿到
package com.jiangxian.reflect;

import java.lang.reflect.Field;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class MyReflectDemo02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = Class.forName("com.jiangxian.reflect.Student");

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName());
        }
    }
}

获取成员变量并修改值:

方法说明
void set(Object obj, Object value)赋值
Object get(Object obj)获取值
package com.jiangxian.reflect;

import java.lang.reflect.Field;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class Field_ {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
        Student s = new Student("JiangXian", 21);
        System.out.println(s);

        Class clazz = Class.forName("com.jiangxian.reflect.Student");
        Field field = clazz.getDeclaredField("name");
        field.setAccessible(true);
        field.set(s,"FengJiu");
        System.out.println(s);

        String n = (String) field.get(s);
        System.out.println("name:" + n);
    }
}


反射获取成员方法:

规则:

  • get 表示获取;
  • Declared 表示私有;
  • 最后的 s 表示所有,复数形式;
  • 若当前获取到的是私有的,那么我们必须要临时修改访问权限,否则无法使用。
方法名说明
Method[] getMethods()返回所有成员方法对象的数组(只能拿public的)
Method[] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到
Method getMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象,存在就能拿到
package com.jiangxian.reflect;

import java.lang.reflect.Method;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class MyReflectDemo03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class clazz = Class.forName("com.jiangxian.reflect.Student");

        System.out.println("=========================");
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("=========================");
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method);
        }

        System.out.println("=========================");
        Method method = clazz.getMethod("getAge");
        System.out.println(method);
    }
}

获取成员方法并运行:

方法:

  • Object invoke(Object obj, Object…args)
    • 参数一:用 obj 对象调用该类方法;
    • 参数二:调用方法的传递的参数(若没有就不写)。
    • 返回值:方法的返回值(若没有就不写)
package com.jiangxian.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author JiangXian~
 * @version 1.0
 */
public class Method_ {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clazz = Class.forName("com.jiangxian.reflect.Student");

        Method method = clazz.getMethod("getName");
        Method method1 = clazz.getMethod("setName", String.class);

        Student student = new Student("JiangXian", 21);
        String name = (String) method.invoke(student);
        System.out.println(name);

        method1.invoke(student,"Fengjiu");
        name = (String) method.invoke(student);
        System.out.println(name);
    }
}

etName");
Method method1 = clazz.getMethod(“setName”, String.class);

    Student student = new Student("JiangXian", 21);
    String name = (String) method.invoke(student);
    System.out.println(name);

    method1.invoke(student,"Fengjiu");
    name = (String) method.invoke(student);
    System.out.println(name);
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江弦凤歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值