java 反射

一、概念

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

   作用:在运行时判断任意一个对象所属的类、在运行时构造任一个类的对象、在运行时判定任一个类具有的成员变量和方法、在运行时调用任意一个对象的方法、生成动态代理。

二、背景

  既然已经有类和对象,为什么获得属性和方法还要用到反射反射机制呢?不能直接调用对象的方法吗???注意条件“在运行时”,有何特殊意义,那就需要知道java的加载过程:

首先一个java文件通过javac编译成.class文件,当我们执行初始化时,会将.class文件通过类加载器加载到jvm中,中间有加载、链接、初始化,在加载的过程中会在java堆中创建一个java.lang.Class的对象,这个对象就代表这类相关的信息,这就是静态加载,即编译时已经知道具体的类。假如编译时没有指明具体的类,该何如创建对象呢?此时就需要就可以利用java反射功能利用Class这个类去实现。网上流行的一张图如下

 

  

场景:

java编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射,如果编码时不知道类或对象的具体信息,此时应该使用反射来实现,比如类的名称放在xml文件中,属性和属性值放在xml文件中,需要在运行时读取xml文件,动态获取类的信息,在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现改对象和类的真实信息。

try {
String classPackage= PacketDispatcher.getName(packetType);
Class<?> clz = Class.forName(classPackage);
Object o = clz.getDeclaredConstructor().newInstance();
Method m = o.getClass().getMethod("execPacket", Object.class); //方法名 参数类型类
m.invoke(o, command); //对象 参数列表
}catch (InstantiationException ex){
ex.printStackTrace();
}

 那么new对象方式和反射有什么区别呢?

 new:编译期已经确定类型,性能好,但灵活性不强

 反射:使用时动态调用创建,灵活但性能差,在框架中大量使用。

三、获取反射入口

 1、对象.getClass()    //对象都取得了,为什么还要反射?不常用

     Person person = new Person();     Class perClazz=person.getClass();   

2、类名.class   //严格要求限定名,并且需要导包,不常用

     Class perClazz= Person.class ; 

3、Class.forName("全类名"); // 常用

    Class <Person>  perClazz = Class.forName("xxx.yy.Person");

    Class <?>  perClazz = Class.forName("xxx.yy.zz");

 

  Method[] methods = perClazz.getMethods();
                //遍历所有方法
        for (Method method : methods) {
            System.out.println(method);
        }

四、Class

  Class这个类保存的是一个java类的meta信息(元信息),反射是由Class类对象开始的,从Class对象中可以获得该类的全部成员、所有类型、包、方法、父类等,Class实例就是指JVM中的一份字节码。

Class<User> clz1 = User.class; 或者 Class<?>  clz2 = Class.forName("cn.itcast.cd.User");因为传的是字符串,此时Class不知道类,使用泛型"?"

五、优秀博文

 https://blog.csdn.net/a745233700/article/details/82893076

 https://blog.csdn.net/ju_362204801/article/details/90578678

posted @ 2021-06-15 16:56  zhangtianhong511  阅读(56)  评论(0)    收藏  举报