java 反射

java 反射

1. java 反射机制的概念

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

2. java 文件和 .class 文件的关系

java 文件

java文件中包含代码的所有内容,类,接口,成员变量,成员方法....

.class 字节码文件

.class 是由 java文件 通过 javac 编译成对应的 .class文件。
在.class 字节码文件中包含了  java 文件的所有内容。
3. 程序加载过程和.class文件的关系

在Java文件运行过程中,当前程序需要哪一个类参与代码执行,那么就需要加载这个类的.class字节码文件,该.class字节码文件时在程序的加载阶段,存在于内存的【代码区】

4. java 中万物皆对象

在java代码中,把内存代码区内保存的.class字节码内存空间,看做成一个对象,这个对象包含了java文件的所有内容。

反射是将数据类型占用的内存代码块空间看成一个Class对象,在这个对象中我们可以获得所有内容,包括私有的成员方法和私有的成员变量。

5. 反射必会方法【重点】
5.1 获取class 类对象的方法
  1. Class Class.forName(String packageNameAndClassName);
    Class类的静态成员方法,通过完整的包名.类名获取对应.class文件的Class对象
  2. Class 类名.class;
    通过类名.class方法,获取对应的Class类对象,通常用于方法的参数类型。
  3. Class 类对象.getClass();
    通过类对象获取对应.class的Class类对象,方法参数,或者说数据类型判断。
Class<?> forName = Class.forName("com.qfedu.a_reflect.Person");

Class<com.qfedu.a_reflect.Person> cls = Person.class;

Class<? extends Person> class1 = new Person().getClass();

这三个class 对象都是同一个Class对象
特点:

1. Class对象对应的是在内存代码区的.class文件占用的内存空间
2. Class引用数据类型变量保存的就是当前空间首地址
3. Java程序中,.class字节码文件有且之加载一次
4. .class文件占用的空间独一份,不管通过哪一种方式获取对应的Class类对象,都是同一个对象
5.2 Constructor 构造方法类涉及到的方法
  1. public Constructor[] getConstructors();
    获取当前Class类对象对应Java文件中,所有【public修饰构造方法的类对象数组】
  2. public Constructor[] getDeclaredConstructors();
    获取当前Class类对象对应Java文件中,所有【构造方法的类对象数组】,包括私有化构造方法。
  3. public Constructor getConstructor(Class… initArgumentTypes);
    根据指定的数据类型,来选择对应的构造方法,这里可能会抛出异常。只能获取public修饰的方法。
  4. public Constructor getDeclaredConstructor(Class… initArgumentTypes);
    根据指定的数据类型,来选择对应的构造方法,这里可能会抛出异常。这里可以获取指定参数类型私有化构造方法和非私有化构造方法
  5. Object newInstance(Object… initArguments);
    通过Constructor对象来调用,传入当前构造方法所需创建对象的初始化参数,创建对象。
Class<?> cls = Class.forName("com.qfedu.a_reflect.Person");//
//获取当前Person类内所有public构造方法
Constructor<?>[] constructors = cls.getConstructors();

for (Constructor<?> constructor : constructors) {
	System.out.println(constructor);
}

//暴力反射,获取Person类内所有的构造方法,包括私有化构造方法
Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();

or (Constructor<?> constructor : declaredConstructors) {
	System.out.println(constructor);
}
5.3 Method 成员方法
  1. Method[] getDeclaredMethods();
    获取类内所有public修饰的成员方法,包括从父类继承而来的public修饰方法。
  2. Method[] getDeclaredMethods();
    获取类内所有成员方法,但是不包括从父类继承而来的方法。
  3. Method getMethod(String methodName, Class… parameterTypes);
    根据指定的方法名和对应的参数类型,获取对应的public修饰的成员方法
  4. Method getDeclaredMethod(String methodName, Class… parameterTypes);
    根据指定的方法名和对应的参数类型,获取对应的成员方法,包括私有化成员方法,但是不
    包括从父类继承而来的方法
  5. Object invoke(Object obj, Object… arguments);
    通过Method类对象调用,执行对应的方法,需要的参数
Class<?> cls = Class.forName("com.qfedu.a_reflect.Person");

//获取类内所有public修饰的成员方法,包括从父类继承而来的方法
Method[] methods = cls.getMethods();
for (Method method : methods) {
	System.out.println(method);
}
根//据指定的方法名和参数类型,获取类内public修饰的成员方法
Method game1 = cls.getMethod("game");
Method game2 = cls.getMethod("game", String.class);

Object obj = cls.getConstructor().newInstance();
//执行public修饰的成员方法
game2.invoke(obj, "WOT");

5.4 Field成员变量涉及到方法
  1. Field[] getFields();
    获取类内所有public修饰的成员变量
  2. Field[] getDeclaredFields();
    获取类内所有成员变量,包括私有化成员方法
  3. Field getField(String fieldName);
    获取指定变量名的成员变量对象,要求是public修饰的成员变量
  4. Field getDeclaredField(String fieldName);
    获取指定变量名的成员变量对象,包括private私有化修饰的成员变量
  5. void set(Object obj, Object value);
    设置指定调用者中对应成员变量的数据
  6. Object get(Object obj);
    获取指定调用者中指定成员变量的数据
Class<?> cls = Class.forName("com.qfedu.a_reflect.Person");

Object obj = cls.getConstructor().newInstance();

field.set(obj, 20);
//给予权限
id.setAccessible(true);
name.setAccessible(true);

id.set(obj, 1);
name.set(obj, "小米");
5.5 给予暴力反射私有化内容的权限操作

setAccessible(boolean flag);
给予Constructor,Method, Field对象,私有化内容,操作权限设置
true表示可以操作

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值