一.Java中反射的概念
在Java中的反射机制,被称为Reflection。它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的package、 type parameters、 superclass、implemented interfaces、Inner class、outer class、fields、construtors、methods、modifier等,并可以在执行的过程中,动态的生成instance、变更fields内容或调用methods。总之一句话,Java反射就是动态的使用类。
二.实例化Class类,有三种方法:
1.如果直接有一个类的对象 比如:
Person p = new Person();
Class clazz = p.getClass();
2.如果知道类名,比如
Class clazz = Person.class;
3.如果只带全类名的话,比如:
String className = "com.java.Person";
Class clazz = Class.forName(className);
类名不确定的类的镜象
三.代码示例:
要被反射的类的代码ModelClass.java
1 package test.java.reflection;
2
3 public class ModelClass {
4 private int id;
5 private String name;
6
7 public ModelClass(){
8
9 }
10
11 public ModelClass(int id,String name){
12 this.id = id;
13 this.name = name;
14
15 }
16
17 public ModelClass(int id){
18 this(id,"xiaohu");
19 }
20
21 public ModelClass(String name){
22 this(18,name);
23 }
24
25 public int getId() {
26 return id;
27 }
28
29 public void setId(int id) {
30 this.id = id;
31 }
32
33 public String getName() {
34 return name;
35 }
36
37 public void setName(String name) {
38 this.name = name;
39 }
40
41
42
43 }
1.根据类名获取类中所有的构造方法,以及参数类型,并打印
Class clazz = Class.forName(className);
claszz.getConstrctors();//返回类型是Constructor数组,此方法不能获取私有的(private)类型的构造函数
clazz.getDeclaredConstructors();//返回类型是Constructor数组,获取类中所有的构造函数,包括private类型的。
clazz.getConstructor(Class... parameterTypes);//获取特定参数的构造函数,参数的类型是Class类型的。此方法不能获取私有的构造函数
clazz.getDeclaredConstructor(Class... parameterTypes);//获取特定参数的构造函数,参数的类型是Class类型的。此方法能获取所有的构造函数,包括私有(private)的
Constructor类有个方法 getModifiers()返回值是int型的,int值对应一个修饰符。用Modifier.toString(int ) 可以获取到那个int值所对应的修饰符的Sring类型。
具体代码如下:
1 public static void getReflectionConstructors(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
2 System.out.println("获取 "+className+" 类中的所有构造方法");
3 //获取类的class镜像
4 Class clazz = Class.forName(className);
5 //获取构造器类的额的数组
6 Constructor[] constructors = clazz.getDeclaredConstructors();
7 for(int i=0;i<constructors.length;i++){
8 int modi = constructors[i].getModifiers();
9 String modifier = Modifier.toString(modi);
10 System.out.print(modifier +" " +className+" (");
11 Class[] paramters = constructors[i].getParameterTypes();
12 for(int j=0;j<paramters.length;j++){
13 if(j!=0) System.out.print(",");
14 System.out.print(Modifier. toString(paramters[j].getModifiers())+" "+paramters[j].getName());
15 }
16 System.out.println(")");
17 }
18 }
结果截图如下:
2.获取类中的所有属性的数据类型和修饰符,并打印
1 public static void getReflectionFelds(String className) throws ClassNotFoundException{
2 System.out.println("获取 "+className+" 类中的所有属性");
3 //获取类的镜象
4 Class clazz = Class.forName(className);
5 Field[] fields = clazz.getDeclaredFields();
6 for(int i=0;i<fields.length;i++){
7 System.out.println(Modifier.toString(fields[i].getModifiers())+" "+fields[i].getName());
8 }
9 }
结果如下截图:
3.获取类中所有方法,并打印
1 public static void getReflectionMethods(String className) throws ClassNotFoundException{
2 System.out.println("获取 "+className+" 类中的所有普通方法");
3 //获取类的镜像
4 Class clazz = Class.forName(className);
5 //获取所有方法对应的类的数组
6 Method[] methods =clazz.getDeclaredMethods();
7 //遍历所有方法
8 for(int i=0;i<methods.length;i++){
9 //获取所有方法的修饰符 ,返回值类型,方法名
10 System.out.print(Modifier.toString(methods[i].getModifiers())+
11 " "+methods[i].getReturnType().getName()+
12 " "+methods[i].getName()+"(");
13 //获取所有参数的类型对应的镜像
14 Class[] parametersType = methods[i].getParameterTypes();
15 for(int j = 0;j<parametersType.length;j++){
16 System.out.print(parametersType[j].getName());
17 if(parametersType.length>j+1)
18 System.out.print(",");
19 }
20 System.out.println(")");
21 }
22
23 }
结果如下截图:
4.根据类名创建实例,并根据类属性的名称,选择要调用的方法获取属性值
代码如下:
1 public static void getReflectionInstatnce(String className) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
2 System.out.println("根据类名 "+className+" 创建实例并根据类属性的名称选择要调用的方法获取属性值");
3 Class<?> clazz = Class.forName(className);
4 Constructor<?> constructor = clazz.getDeclaredConstructor(int.class,String.class);
5 ModelClass model = (ModelClass) constructor.newInstance(18,"xiaohu");
6 //System.out.println("id = "+model.getId()+" name = "+model.getName());
7 Field[] fields = clazz.getDeclaredFields();
8 for(int i=0;i<fields.length;i++){
9 //获取属性名的第一个字母,并转换为大写
10 String leftFirst = fields[i].getName().substring(0, 1).toUpperCase();
11 //获取属性名第一个字母以后的其他字符
12 String right = fields[i].getName().substring(1);
13 //拼接出get方法的名字
14 String methodName = "get"+leftFirst+right;
15 Method method = clazz.getDeclaredMethod(methodName);
16 System.out.println(fields[i].getName()+" = "+method.invoke(model));
17
18 }
19 }
结果如下:
据类名 test.java.reflection.ModelClass 创建实例并根据类属性的名称选择要调用的方法获取属性值
id = 18
name = xiaohu