Java基础-反射

反射就是把Java类中的各个成员映射成一个个的Java对象。

即在运行状态中
1、对于任意一个类,都能知道这个类的所有属性和方法。
2、对于任意一个对象,都能调用它的任意一个属性和方法。
这种动态获取信息以及动态调用对象方法的功能叫做Java的反射机制。

1、对象创建过程

为什么在介绍反射的时候需要先介绍对象创建过程?
通过对象创建,引出Class对象

image.png

  1. 通过javac命令把Java源代码编译成class文件
  2. 类加载器加载class文件到内存
  3. 类元信息存放在方法区。(类元信息:类、方法等字节码信息)
  4. 创建类对应的Class对象,放在堆区。(每个类只会创建一个Class对象,作为方法区类的数据结构的接口。jvm创建对象前,会先检查类是否被加载,寻找类对应的Class对象)

2、反射的原理

  • 反射机制允许程序在执行期间借助于ReflectionApi取得任何类的内部信息(比如成员变量、构造器、成员方法等),并能操作对象的属性和方法。
  • 加载完类后,在队中就产生了一个Class对象,这个对象包含了类的完整结构信息。通过这个对象可以得到类的结构。

3、反射的作用

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任何一个类的对象
  • 在运行时得到任意一个类所具有的的成员变量和方法
  • 在运行时调用任意一个对象的成员变量和方法
  • 生成动态代理

4、反射的相关类

Java反射机制的实现主要借助以下4个类:

  • java.lang.Class:代表一个类,Class对象是类被加载后,在堆中的对象
  • java.lang.reflect.Method:代表类的方法
  • java.lang.reflect.Field:代表类的成员变量
  • java.lang.reflect.Constructor:代表类的构造方法

5、反射的使用

5.1 如何获取Class对象

  1. 类.class
  2. 对象.getClass()
  3. Class.forName(全类名)
package reflect;

/**
 * 获取Class对象
 *
 * @author zhao.hualuo
 * Create at 2022/4/28
 */
public class GetClass {

    public static void main(String[] args) throws ClassNotFoundException {
        //类.class
        Class<GetClass> aClass = GetClass.class;
        System.out.println(aClass.getName());

        //对象.getClass()
        GetClass getClass = new GetClass();
        Class<? extends GetClass> bClass = getClass.getClass();
        System.out.println(bClass.getName());

        //Class.forName(全类名)
        Class<?> cClass = Class.forName("reflect.GetClass");
        System.out.println(cClass.getName());
    }
}

5.2 通过Class对象进行反射

package reflect;

import java.lang.reflect.Method;

/**
 * 反射Demo
 *
 * @author zhao.hualuo
 * Create at 2022/4/28
 */
public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        //1、获取Class对象
        Class<ReflectDemo> demoClass = ReflectDemo.class;

        //2、利用Class对象获取对象全部信息
        System.out.println("get " + demoClass.getClassLoader());
        System.out.println("get " + demoClass.getConstructors());
        System.out.println("get " + demoClass.getMethods());
        System.out.println("get " + demoClass.getMethod("sayHello", String.class));
        System.out.println("get " + demoClass.getMethod("sleep", int.class));
        System.out.println("get " + demoClass.getFields());
        System.out.println(" ");

        //3、利用Class对象可任意调用类方法
        ReflectDemo demo = demoClass.newInstance();

        Method method = demoClass.getMethod("sayHello", String.class);
        method.invoke(demo, "张三");

        Method[] methods = demoClass.getMethods();
        methods[1].invoke(demo, 7);
    }

    public static void sayHello(String name) {
        System.out.println("hello " + name);
    }

    public static void sleep(int num) {
        System.out.println("sleep " + num + " hour");
    }
}

执行结果:

"D:\Program Files\Java\jdk1.8.0_281\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:62399,suspend=y,server=n -javaagent:C:\Users\zhao.hualuo\AppData\Local\JetBrains\IdeaIC2021.3\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_281\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_281\jre\lib\rt.jar;D:\CodeWorkspace\Demo\target\production\Demo;D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3\lib\idea_rt.jar" reflect.ReflectDemo
Connected to the target VM, address: '127.0.0.1:62399', transport: 'socket'
get sun.misc.Launcher$AppClassLoader@18b4aac2
get [Ljava.lang.reflect.Constructor;@4d591d15
get [Ljava.lang.reflect.Method;@65ae6ba4
get public static void reflect.ReflectDemo.sayHello(java.lang.String)
get public static void reflect.ReflectDemo.sleep(int)
get [Ljava.lang.reflect.Field;@48cf768c
 
hello 张三
sleep 7 hour
Disconnected from the target VM, address: '127.0.0.1:62399', transport: 'socket'

Process finished with exit code 0

获取的methods为:
image.png

6、反射的优化

Method、Field、Constructror对象都有setAccessible()方法。
setAccessible():启用或者禁用访问安全检查。true代表取消访问检查,false代表执行访问检查
关闭安全检查可以提高反射效率

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值