反射的意义:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。(说的直白点就是为了代码简洁,提高代码的复用率,外部调用方便,源代码,反编译都能看到。)
package avicit.mms.common; interface Animal { //动物接口 public void say() ; //叫声 } class Dog implements Animal{ //定义狗 public void say() { System.out.println("汪、汪、汪!!!"); } } class Cat implements Animal{ public void say() { System.out.println("喵、喵、喵!!!"); } } class Factory{ public static Animal getInstance(String className){ Animal animal = null ; try{ animal = (Animal) Class.forName(className).newInstance() ; }catch(Exception e ){ e.printStackTrace() ; } return animal ; } } public class Test{ public static void main(String args[]){ //通过工厂类取得接口实例,传入完整的包.类名称 Animal animal = Factory.getInstance("avicit.mms.common.Dog") ; if(animal!=null){ //判断是否取得接口实例 animal.say() ; } } }
输出:
汪、汪、汪!!!
如果不用反射,那么我们如果再加一个老虎类,就得在Factory里判断,每添加一个类都要修改一次Factory,但用了反射只用在调用的时候传入完整的类名就可完成。结果:用反射,修改一处代码;不用反射,修改两处代码。
反射一般用于:
- JDBC中,利用反射动态加载了数据库驱动程序。
- Web服务器中利用反射调用了Sevlet的服务方法。
- Eclispe等开发工具利用反射动态刨析对象的类型与结构,动态提示对象的属性和方法。
- 很多框架都用到反射机制,注入属性,调用方法,如Spring。
反射机制的优缺点:
- 优点:可以动态执行,在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。
- 缺点:对性能有影响,这类操作总是慢于直接执行java代码。
反射机制的作用:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
反射的使用:
- 通过一个全限类名创建一个对象
- Class.forName(“全限类名”); 例如:com.mysql.jdbc.Driver Driver类已经被加载到 jvm中,并且完成了类的初始化工作就行了
- 类名.class; 获取Class<?> clz 对象
- 对象.getClass();
- 获取构造器对象,通过构造器new出一个对象
- Clazz.getConstructor([String.class]);
- Con.newInstance([参数]);
- 通过class对象创建一个实例对象(就相当与new类名()无参构造器)
- Cls.newInstance();
- 通过class对象获得一个属性对象
- Field c=cls.getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
- Field c=cls.getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段
- 通过class对象获得一个方法对象
- Cls.getMethod(“方法名”,class……parameaType);(只能获取公共的)
- Cls.getDeclareMethod(“方法名”);(获取任意修饰的方法,不能执行私有)
- M.setAccessible(true);(让私有的方法可以执行)
- 让方法执行
- Method.invoke(obj实例对象,obj可变参数);-----(是有返回值的)
package avicit.mms.common; import java.lang.reflect.*; public class Main { public static void main(String[] args) throws Exception{ //返回A的构造方法 Constructor c = A.class.getConstructor(); //返回A类的所有为public 声明的构造方法 Constructor[] cons = A.class.getConstructors(); //返回A类所有的构造方法,包括private Constructor[] cons2 = A.class.getDeclaredConstructors(); //返回A类的第一个public 方法 Method m = A.class.getMethod("say"); //执行 m.invoke(A.class.newInstance(), null); //返回A类所有的public 方法 Method[] ms = A.class.getMethods(); //返回A类所有的方法,包括private Method[] allMs = A.class.getDeclaredMethods(); //返回A类的public字段 Field field = A.class.getField("i"); System.out.println(field.get(A.class.newInstance())); //返回A类的static 字段 System.out.println(field.get(null)); } } class A{ public int i = 1; public static int b = 2; public A(){ System.out.println("无参构造"); } private A(String s){ System.out.println("有参构造"+s); } public void say(){ System.out.println("say"); } }