1.什么是反射? 必须是运行的状态下,都能够获取到这个类的所有的属性和方法。 对于类中的任意一个对象对象,都能够调用它的任意一个方法和属性。 这种动态获取的信息以及这种动态调用的对象的方法的功能就是java中反射 2.理解Class类? Class 对象只能由系统建立对象 –一个类在 JVM 中只会有一个Class实例 –每个类的实例都会记得自己是由哪个 Class 实例所生成 3..该才能怎样执行反射机制? 就必须先要获取到该类的字节码文件对象(。class), 每一一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码对象 3.获取字节码文件对象的三种方式 Class cla = Class.forName("包名+类名");//此时为源文件阶段,并没有改变字节码文件 Class cla1 = person.class;//获取自己,字节码阶段 Class cla2 = p.getClass();//创建对象的状态 有了字节码文件对象才能获得类中所有的信息 4.掌握 Constructor、Method、Field 类的用法 Constructor 1).Field[] getFields():获取所有的"公有字段" 2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有; 2.获取单个的: 1).public Field getField(String fieldName):获取某个"公有的"字段; 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的) 设置字段的值: Field --> public void set(Object obj,Object value): 参数说明: 1.obj:要设置的字段所在的对象; 2.value:要为字段设置的值; new 和newInstance的区别: 从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载; 但是使用newInstance时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。 有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。 newInstance: 弱类型。低效率。只能调用无参构造。 new: 强类型。相对高效。能调用任何public构造。 通俗来讲:
每创建完一个类就会生成一个独一的 (.class) 文件,创建之后jvm会自动分配到一块空间内存来存储,然后一个类只能产生一个class对象,只有通过拿到产生的唯一的class对象来实现java反射机制来获取类中的所有信息,共有私有都可以过去到;他就会变成一个透明的类 //获取字节码方式三种 //第一种 Student stu = new Student(); Class class1 = stu.getClass(); System.out.println(class1); //第二种 Class class2 = Student.class; System.out.println(class2); //第三种 Class class3 = Class.forName("cn.happy.reflect.Student"); System.out.println(class3); System.out.println("获取公有的字段"); Field[] getreflector = class3.getFields(); for (Field field : getreflector) { System.out.println(field); } System.out.println("获取指定公有的字段"); Field getreflector2 = class3.getField("name"); System.out.println(getreflector2); System.out.println("获取所有的字段"); getreflector = class3.getDeclaredFields(); for (Field field : getreflector) { System.out.println(field); } //获取字段并赋值 System.out.println("获取指定公有的字段并赋值"); Field getreflector3 = class3.getField("name"); System.out.println(getreflector3); Object obj = class3.newInstance(); getreflector3.set(obj, "鬼鬼"); Student stus = (Student)obj; stus.name="啦啦"; System.out.println(getreflector3.get(stus)); System.out.println("****************"); System.out.println(stus.name); } 有了字节码文件对象才能获得类中所有的信息 通俗来讲: 有了字节码文件对象就可进行反射获取对象中的属性 总结 在反射机制概述中,我们了解到了java的一个动态特性:反射 知道了反射机制是一种动态获取信息以及动态调用对象方法的功能。 通过反射我们可以在运行时判断任意一个对象所属的类,在运行时构造任意一个类的对象,判断任意一个类所具有的方法和属性,同时,也可以在运行时调用任意一个对象的方法以及生成动态代理,如果编译时我们根本无法预知该对象或类可能属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,那么此时我们就必须使用反射。 事实上,在我们平时写代码的时候反射技术用的并不是很多,因为通过反射创建对象时性能要稍微低一些,只有当程序需要动态创建某个类的对象时才会使用反射Class类是反射的核心类。