疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java反射的理解


 

   

  反射的作用:

  1.运行时检查类的结构

  2.运行时更改类的字段值

  3.调用类的方法

  准备知识:

  Class类:虚拟机为每一个对象保存的一份对象所属类的清单:

  static Class forName(String className) 获取字符串(接口或者类的全类名)对应的类的Class对象。

  Object newInstance() 返回Class对应的类的一个对象

  解析:

  1.运行时检查类的结构

  java.lang.reflection 中有三个类:

  1.Field 对应类的字段

  getName() 返回Field对应的名称

  getType() 返回Field所在的Class类型

  2.Method 对应类的方法

  getName() 返回Method 对应的名称

  Class[] getParameterTypes() 按方法声明的顺序返回参数类型数组

  int getModifiers() 返回一个整数值,用不同的位开关表示static,public这样的修饰情况。

  3.Constructor 对应构造器

  getName() 返回Constructor 对应的名称

  Class[] getParameterTypes() 按方法声明的顺序返回参数类型数组

  int getModifiers() 返回一个整数值,用不同的位开关表示static,public这样的修饰情况。

  在Method和Constructor中可以使用Modifier类的isPrivate,isStatic 来判断getModifiers()的返回值,给出是否含有对应的修饰符。

  Class对象的getDeclaredConstructors,getDeclaredMethods,getDeclaredFields分别用于获取对象的构造器,方法,字段,以数组的形式返回。

  下面为反射基本用法:检测一个类的结构:

  

  1 import java.lang.reflect.Constructor;

  2 import java.lang.reflect.Field;

  3 import java.lang.reflect.Method;

  4 import java.lang.reflect.Modifier;

  5

  6 //反射基本测试

  7 public class ReflectionTest {

  8 public static void main(String[] args) {

  9 String name = "java.util.Date";

  10 try {

  11 Class cl = Class.forName(name);

  12 Class supercl = cl.getSuperclass();

  13 String modifiers = Modifier.toString(cl.getModifiers());

  14 if (modifiers.length() > 0) System.out.print(modifiers + " ");

  15 System.out.print("class " + name);

  16 if (supercl != null && supercl != Object.class) System.out.print(" extends "

  17 + supercl.getName());

  18

  19 System.out.print(" { ");

  20 printConstructors(cl);

  21 System.out.println();

  22 printMethods(cl);

  23 System.out.println();

  24 printFields(cl);

  25 System.out.println("}");

  26 } catch (ClassNotFoundException e) {

  27 e.printStackTrace();

  28 }

  29 System.exit(0);

  30 }

  31

  32

  33 public static void printConstructors(Class cl) {

  34 Constructor[] constructors = cl.getDeclaredConstructors();

  35

  36 for (Constructor c : constructors) {

  37 String name = c.getName();

  38 System.out.print(" ");

  39 String modifiers = Modifier.toString(c.getModifiers());

  40 if (modifiers.length() > 0) System.out.print(modifiers + " ");

  41 System.out.print(name + "(");

  42

  43 // print parameter types

  44 Class[] paramTypes = c.getParameterTypes();

  45 for (int j = 0; j < paramTypes.length; j++) {

  46 if (j > 0) System.out.print(", ");

  47 System.out.print(paramTypes[j].getName());

  48 }

  49 System.out.println(");");

  50 }

  51 }

  52

  53

  54 public static void printMethods(Class cl) {

  55 Method[] methods = cl.getDeclaredMethods();

  56

  57 for (Method m : methods) {

  58

  59 Class retType = m.getReturnType();

  60 String name = m.getName();

  61

  62 System.out.print(" ");

  63 // print modifiers, return type and method name

  64 String modifiers = Modifier.toString(m.getModifiers());

  65 if (modifiers.length() > 0) System.out.print(modifiers + " ");

  66 System.out.print(retType.getName() + " " + name + "(");

  67

  68 // print parameter types

  69 Class[] paramTypes = m.getParameterTypes();

  70 for (int j = 0; j < paramTypes.length; j++) {

  71 if (j > 0) System.out.print(", ");

  72 System.out.print(paramTypes[j].getName());

  73 }

  74 System.out.println(");");

  75 }

  76 }

  77

  78

  79 public static void printFields(Class cl) {

  80 Field[] fields = cl.getDeclaredFields();

  81

  82 for (Field f : fields) {

  83 Class type = f.getType();

  84 String name = f.getName();

  85 System.out.print(" ");

  86 String modifiers = Modifier.toString(f.getModifiers());

  87 if (modifiers.length() > 0) System.out.print(modifiers + " ");

  88 System.out.println(type.getName() + " " + name + ";");

  89 }

  90 }

  91 }

  复制代码

  2.更改类的字段值:

  Field对象有以下对应的一系列方法:

  public Object get(Object obj) 获取目标对象上字段的值

  public void set(Object obj, Object value)设置目标对象上字段的值

  有相应具体类型的get和set方法。

  3.调用类的方法(类似于方法指针):

  Method对象方法:

  public Object invoke(Object obj, Object... args)

  obj是调用的目标对象,ars是方法参数

  以下为示例代码:

  复制代码

  1 import java.lang.reflect.Field;

  2 import java.lang.reflect.InvocationTargetException;

  3 import java.lang.reflect.Method;

  4

  5 /**

  6 * Created by karlx on 2015/5/29.

  7 */

  8 public class ReflectionTest2 {

  9 public static void main(String[] args) {

  10 Person person = new Person();

  11 person.name = "karl";

  12 //获取,设置 运行中对象的字段值

  13 Class clazz = person.getClass();

  14 try {

  15 Field field = clazz.getField("name");

  16 field.setAccessible(true);//避开java的访问检查

  17 System.out.println(field.get(person));

  18

  19 field.set(person, "xiaoming");

  20 System.out.println(field.get(person));

  21

  22 } catch (NoSuchFieldException | IllegalAccessException e) {

  23 e.printStackTrace();

  24 }

  25 //运行中调用对象的方法

  26 try {

  27 Method method = clazz.getMethod("getName");

  28 method.setAccessible(true);//避开java的访问检查

  29 System.out.println(method.invoke(person));

  30 } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException

  e) {

  31 e.printStackTrace();

  32 }

  33 }

  34

  35 static class Person {

  36 public String name;

  37

  38 public String getName() {

  39 return name + "hello";

  40 }

  41

  42 public void setName(String name) {

  43 this.name = name;

  44 }

  45 }

  46 }

  复制代码