反射技术概念:
动态加载一个类,得到这个类中的所有内容。而且将字节码文件封装在一个对象中(Class对象),并将字节码中的内容都封装成对像,这样便于操作这些成员。可以说反射技术大大地增强了程序的扩张性,因为一个类进行解刨后,可以对他进行很多操作。
反射的基本步骤:
①得到类的字节码,将这个类的字节码封装在Class对象中
②实例化对象,获得类的属性、方法和够着函数。
③访问属性、调用方法、使用够着函数创建对象。
获取Class对象的三个方法:
①通过一个类的对象,可以得到该类的字节码,格式为:对象名.getClass();
Object obj = new Demo();
Class clazz = obj.getClass();
②通过类名,直接获取该类的字节码,格式为:类名.class;
Class clazz = Demo.class;
③使用Class类的forName方法,获取指定的类的字节码,格式为:Class.forName(“指定类名”),这种方式的扩张性强,因为我们不需要知道该类是否存在就可以编译通过,在使用时建议使用这中方式获取指定类的字节码。
Class clazz = Class.forName("cn.itcast.luntan.Dmeo");
反射的用法:
①反射类的构造函数
Class clazz = Demo.class;
Constructor con = class.getConstructor("参数列表");
con.newInstance("参数列表");//创建对象
当然,这里获取的是有参数的构造函数,这样一来在使用newInstance的时候必须指定一个参数,为了便于扩展,在被反射的类中,我们通常要设置一无参构造函数,这样创建对象的时候就不用传递参数了。
当然,如果没有无参的构造函数,那必须获取到指定参数的构造函数,使用该函数来进行实例化。
②反射类成员方法
Class clazz = Class.forName("cn.itcast.luntan.Demo");
Method method = clazz.getMethod(方法名称,方法参数);
③反射字段
Demo demo = new Demo();
Class clazz = demo.getClass();
Field field = clazz.getField(字段名);
field.setAccessible(true);//暴力反射
field.setObject(value);//设置字段值
获取类中的所有方法:
Class clazz = Class.forName("cn.itcast.luntan.Demo");
Method[] method = clazz.getMethods();//获取公有方法和父类中的公有方法;
methods = clazz.getDeclareMethod();//获取本类中的所有方法,包括私有方法
for(Method method : methods){
}
Method method = clazz.getMethod("show",int.class);
method.invoke(clazz,56);//执行指定类中的指定参数的方法
如果想要得到一个类中的私有方法
那么通过getDeclareMethod得到所有方法,但是私有方法时不能直接访问的,如果要访问,就要使用暴力反射
method.setAccessible(true);//一般很少用,既然都谁是私有的了,当然是不想让人访问了
因为静态方法不属于任何类,所以静态方法在被反射的时候,就不需要指定在那个对象上的方法,(没有你怎么指定啊)
Class clazz = Class.forName("cn.itcast.luntan.Demo");
Method method = clazz.getMethod("function",int.class);
method.invoke(null,56);//这里不需要指定在那个对象上调用方法