反射:
其实就是动态的从内存加载一个指定的类,并获取该类中的所有的内容。
反射的好处:大大的增强了程序的扩展性。
反射的基本步骤:
获得Class对象,就是获取到指定的名称的字节码文件对象。
实例化对象,获得类的属性、方法或构造函数。
访问属性、调用方法、调用构造函数创建对象。
一、 获取Class对象,有三种方式 :
通过每个对象都具备的方法getClass来获取。弊端:必须要创建该类对象,才可以调用getClass方法。
每一个数据类型(基本数据类型和引用数据类型)都有一个静态的属性class。弊端:必须要先明确该类。 前两种方式不利于程序的扩展,因为都需要在程序使用具体的类来完成。
使用的Class类中的方法,静态的forName方法。指定什么类名,就获取什么类字节码文件对象,这种方式的扩展性最强,只要将类名的字符串传入即可。
1 Class clazz = Class.forName("com.makaruina.reflect.Person" );
二、获取了字节码文件对象后,然后就需要创建指定类的对象: 创建对象的两种方式(其实就是对象在进行实例化时的初始化方式):
调用空参数的构造函数: 使用了Class类中的newInstance()方法。
调用带参数的构造函数: 先要获取指定参数的构造器对象,然后通过该构造器对象的newInstance(实际参数) 进行对象的初始化。
1 2 3 Class clazz = Class.forName("com.makaruina.reflect.Person" );Constructor con = clazz.getConstructor(new Class []{String.class,int .class});Person instance = (Person) con.newInstance("name" ,20 );
综上所述,第二种方式,必须要先明确具体的构造函数的参数类型,不便于扩展。所以一般情况下,被反射的类,内部通常都会提供一个公有的空参数的构造函数。
三、获取类中的方法,属性,构造函数。 1、获取方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public static void method_1 () throws Exception { Class clazz = Class.forName("com.makaruina.reflect.Person" ); Method[] methods = clazz.getMethods(); methods = clazz.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } } public static void method_2 () throws Exception { Class clazz = Class.forName("com.makaruina.reflect.Person" ); Method method = clazz.getMethod("show" , int .class, String.class); Object obj = clazz.newInstance(); method.invoke(obj, 39 , "hehehe" ); } public static void method_3 () throws Exception { Class clazz = Class.forName("com.makaruina.reflect.Person" ); Method method = clazz.getDeclaredMethod("method" , null ); method.setAccessible(true ); } public static void method_4 () throws Exception { Class clazz = Class.forName("com.makaruina.reflect.Person" ); Method method = clazz.getMethod("function" , null ); method.invoke(null , null ); }
2、获取属性
1 2 3 4 5 6 7 8 Field getField (String name) Field[] getFields() Field getDeclaredField (String name) Field[] getDeclaredFields()
3、获取构造函数
1 2 3 4 Constructor<T> getConstructor (Class<?>... parameterTypes) Constructor<?>[] getConstructors()