Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)获得任何一个类的字节码。包括接口、变量、方法等信息。还可以让我们在运行期实例化对象,通过调用get/set方法获取变量的值。
一下我们通过几个小demo来了解java反射的相关知识
首先,我们先定义一个类,以便我们后续能通过反射获取到这个类基本信息
1 class Person { 2 private int age; 3 private String name; 4 5 public Person() { 6 7 } 8 9 public Person(int age, String name) { 10 this.age = age; 11 this.name = name; 12 } 13 14 public int getAge() { 15 return age; 16 } 17 18 public void setAge(int age) { 19 this.age = age; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 @Override 31 public String toString() { 32 return "Person{" + 33 "age=" + age + 34 ", name=‘" + name + ‘\‘‘ + 35 ‘}‘; 36 } 37 } 38 39 class SuperMan extends Person implements ActionInterface { 40 private boolean BlueBriefs; 41 42 public void fly() { 43 System.out.println("超人会飞耶~~"); 44 } 45 46 public boolean isBlueBriefs() { 47 return BlueBriefs; 48 } 49 50 public void setBlueBriefs(boolean blueBriefs) { 51 BlueBriefs = blueBriefs; 52 } 53 54 public void wc(){ 55 System.out.println("超人会嘘嘘"); 56 } 57 58 59 @Override 60 public void walk(int m) { 61 // TODO Auto-generated method stub 62 System.out.println("超人会走耶~~走了" + m + "米就走不动了!"); 63 } 64 } 65 interface ActionInterface{ 66 public void walk(int m); 67 }
一个Person类,子类是superman类,子类还实现了ActionInterface 接口
1.获取类
//可能抛出 ClassNotFoundException Class<?> reflet = Class.forName("com.example.thread.demo.ReflectDemo"); System.out.println("包名"+reflet.getPackage().getName()+"类名:"+reflet.getName());
包名com.example.thread.demo类名:com.example.thread.demo.ReflectDemo
2.实例化对象
ReflectDemo reflectDemo = (ReflectDemo) reflet.newInstance();
3.得到Person的构造函数
1 Constructor<?>[] constructors = reflect.getConstructors(); 2 Person person = (Person) constructors[0].newInstance(); 3 person.setAge(12); 4 person.setName("zs"); 5 System.out.println(person.toString());
Person类有两个构造器,第二行表示的是取第一个构造器也就是无参构造器并实例化对象
4.获取类中的方法
1 Class<?> bClass = Class.forName("com.example.thread.demo.SuperMan"); 2 3 //包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。 4 Method[] declaredMethods = bClass.getDeclaredMethods(); 5 6 //所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。 7 Method[] methods = bClass.getMethods(); 8 9 for(Method method:declaredMethods){ 10 System.out.println("Demo6,取得SuperMan类的方法:"); 11 System.out.println("函数名:" + method.getName()); 12 System.out.println("函数返回类型:" + method.getReturnType()); 13 System.out.println("函数访问修饰符:" + Modifier.toString(method.getModifiers())); 14 System.out.println("函数代码写法: " + method); 15 }
5.获取变量
Field[] declaredFields = aClass.getDeclaredFields();
6.获取变量上的注解
1 Annotation[] annotations = field.getAnnotations(); 2 for(Annotation annotation:annotations){ 3 Class<? extends Annotation> aClass2 = annotation.annotationType(); 4 String name1 = aClass2.getName(); 5 System.out.println(name1); 6 }
好了,其实反射的api就那么几个,重点还是在于反射的思想,反射在java的应用中更多的是在框架层面和注解的使用上,这方面我们后续在做进一步的了解