反射在java中应用地方很多,反射支持java程序在运行中获取某个特定的类的属性方法或者是其他内容,可以无需通过new的形式,大大减小了运行过程中的耦合。比如说某个场景,我需要传入一个参数来决定是加载哪个类,如果方法内部通过ifelse判断,这是一个非常麻烦的过程,同时,也不利于系统的扩展,此时,反射就可以做到动态的加载某个类。如jdbc驱动就可以指定传入的参数来决定加载哪个数据库:
Class.forName("com.mysql.jdbc.Driver)就是一种典型的反射,我们可以通过替换里面的String来替换我们想要使用的数据库。
同时Spring很多地方也是用到了反射机制,Spring中一般是通过反射+注解的形式来判断类是否为特殊的bean,因为通过反射可以获取类的注解,基于注解就能做很多事,这里可以看出反射的重要性。
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.concurrent.ConcurrentLinkedDeque; public class DesignPattern { public static void main(String[] args) throws Exception{ //JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象, //都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制 //通过反射调用类的无参构造器创建出一个变量 Hello hello = Hello.class.newInstance(); //值为5 System.out.println(hello.compute((a, b) -> a + b)); //通过反射还可以获取他的带参构造器 Constructor<Hello> declaredConstructor = Hello.class.getDeclaredConstructor(Integer.class, Integer.class); //通过他的带参构造器实例话对象 Hello hello1 = declaredConstructor.newInstance(1, 2); System.out.println(hello1.compute((a, b) -> a + b)); //反射除了可以实力化对象,还可以获取其中private属性的值(在类未提供对外方法获取属性的时候) Field a = hello.getClass().getDeclaredField("a"); a.setAccessible(true); System.out.println("a的属性 :" + a.getType() + " a的值 : " + a.get(hello)); //反射还可以获取类中的私有方法并调用 Method computePlus = hello.getClass().getDeclaredMethod("computePlus", Do.class); computePlus.setAccessible(true); //调用该私有方法 Object invoke = computePlus.invoke(hello, (Do) (a1, b1) -> a1 * b1); //值为6 System.out.println(invoke); //反射除了可以获得类中的方法,成员变量,还可以获得类中修饰的注解,等等 } } class Hello{ private Integer a = 2; private Integer b = 3; Hello(){ } Hello(Integer a,Integer b){ this.a = a; this.b = b; } public Integer compute(Do doIt){ return doIt.doIt(a,b); } private Integer computePlus(Do doIt){ return doIt.doIt(a,b); } } interface Do{ int doIt(int a,int b); }