Java的反射
1.Java的反射不同于我们平时的new对象。反射只有在运行时才知道要操作的类是什么,从而在运行时获取类的有关信息,包括构造函数,属性,和函数,并调用对应的函数。
Person类
public class Person { private int age; private String name; public int getAge() { return age; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } }
2.我们先体验下什么是反射^_^。。。。我们为上面的Person类创建对象,并调用函数。
Person person = new Person(); person.setName("zhangsan"); person.setAge(25); System.out.println(person.getName() + ":" + person.getAge()); Class clazz = Class.forName("Person"); Constructor constructor = clazz.getConstructor(); Object object = constructor.newInstance(); Method method = clazz.getMethod("setName", String.class); Method method1 = clazz.getMethod("setAge", int.class); method.invoke(object,"lisi"); method1.invoke(object,36); Method method2 = clazz.getMethod("getName"); Method method3 = clazz.getMethod("getAge"); System.out.println(method2.invoke(object) + ":" + method3.invoke(object));
运行结果
zhangsan:25
lisi:36
从上面的代码执行结果可以看出,结果其实都是一样的。第一段代码在未运行时便已确定Person类,所以new出对象。第二种方式,在运行时才通过字符串得知自己运行的类是“Person”。
然后反射调用setName和setAge函数并传递"lisi"和36,最后使用反射调用getName函数,输出其价格。
3.获取反射中Class对象的三种方式
一个类在JVM中只会有一个Class实例。
//通过对象调用getClass()函数来获取 Person person = new Person(); Class clazz = person.getClass(); //通过Class对象的 forName()静态函数获取 Class clazz2 = Class.forName("Person"); //类名.class,每个类都有一个隐含的静态成员变量class Class clazz3 = Person.class; System.out.println(clazz == clazz2 ); System.out.println(clazz == clazz3); System.out.println(clazz2 == clazz3);
运行结果
true true true
4.通过反射创建类对象有两种方式
第一种方式
Person person = new Person(); Class clazz = person.getClass(); //通过Class对的newInstance函数 Object object = clazz.newInstance();
第二种方式
Class clazz2 = Class.forName("Person"); Constructor constructor = clazz2.getConstructor(); //通过Constructor对象创建类对象可以选择特定的构造函数 Object object1 = constructor.newInstance();
5.通过反射获取类属性,函数,构造器
Class clazz = Class.forName("Person"); //输出类名称 System.out.println("我是加载的类名" + clazz.getName()); //获取类的public类型的属性,因为我们都是private私有的。不会输出 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println("我是公有类的名称" + field.getName()); } //获取类的所有属性,包括私有 Field[] fields1 = clazz.getDeclaredFields(); for (Field field : fields1) { System.out.println("所有类的属性名称:" + field.getName()); } //获取类的public类型的函数。这里包括object类的一些函数 Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println("所有函数名称:" + method.getName()); } Method[] methods1 = clazz.getDeclaredMethods(); for (Method method : methods1) { System.out.println("Person类的所有函数" + method.getName()); }
6.反射机制并无神奇之处,与new对象之间的区别在与
编译器在编译时打开和检查.class文件
反射,运行时打开和检查.class文件