反射机制
反射机制可通过在运行时加载类名而获取类,并对其进行操作。工厂模式,动态代理中较常用到。
在实际场景中:由于有好多类具有共同的接口样式,而他们又用的不是很频繁,如果在服务器中保有这些类会占用资源空间,如果通过接口指定的方式去加载,用完之后就销毁掉,可节省资源空间,且实现接口编程,扩展性好,代码量也少。打个比方:哺乳动物Animal为接口,里面包括获取乳头数,获取腿,获取头,获取尾巴等,像这种都具有一定共性,实现类为老虎,狮子,兔子,羊等等等。
1.获取className,常用的形式将需要反射的类放在属性文件*.properties或数据库字段中,通过key获取类名及路径。
1 private static final String CLASS_NAME_PATH = "pattern/classname.properties"; 2 3 /** 4 * 获取类名称 5 * @return 6 */ 7 private static String getClassName(String name) { 8 Properties pro = new Properties(); 9 try { 10 String url = ProxyFactory.class.getClassLoader().getResource("").getPath() + CLASS_NAME_PATH; 11 pro.load(new FileInputStream(url)); 12 } catch (FileNotFoundException e) { 13 e.printStackTrace(); 14 } catch (IOException e) { 15 e.printStackTrace(); 16 } 17 return (String)pro.get(name); 18 }
1 # animal 2 lion = pattern.creation.factory.animal.Lion 3 sheep = pattern.creation.factory.animal.Sheep 4 rabit = pattern.creation.factory.animal.Rabit 5 # plant 6 apple = pattern.creation.factory.plant.Apple 7 pear = pattern.creation.factory.plant.Pear 8 plum = pattern.creation.factory.plant.Plum
>>> String strClass = getClassName("rabit");//获取兔子类
2.获取类,创建类实例
Class<?> clazz = Class.forName(strClass); //获取类
Object obj = clazz.newInstance(); //构建实例对象
Class<?> superClazz = clazz.getSuperclass(); //获取父类
Class<?>[] interfaceArray = clazz.getInterfaces();//获取接口
1 /** 2 * 根据classname获取类名 3 * @param strName 4 * @return 5 * @throws ClassNotFoundException 6 * @throws InstantiationException 7 * @throws IllegalAccessException 8 */ 9 @SuppressWarnings("unchecked") 10 public <T> T getClassByName(String strName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { 11 String strClass = getClassName(strName); 12 Class<?> clazz = Class.forName(strClass); 13 Class<?> superClazz = clazz.getSuperclass(); 14 Class<?>[] interfaceArray = clazz.getInterfaces(); 15 System.out.println("className--: " + clazz.getName());//当前类名 16 System.out.println("superClassName--: " + superClazz.getName());//父类 17 for(Class<?> interfaces: interfaceArray){ 18 System.out.println("interface--: " + interfaces.getName());//接口 19 } 20 return (T)clazz.newInstance(); 21 }
>>> AnimalFactory animal = reflectFactory.getClassByName("rabit");
运行结果:
className--: pattern.creation.factory.animal.Rabit
superClassName--: pattern.creation.factory.animal.Animals
interface--: pattern.creation.factory.animal.AnimalFactory
3. 获取类属性及信息
Field[] fieldArray = clazz.getDeclaredFields(); // 显示所有的属性
Field[] publicFieldArray = clazz.getFields(); //显示public属性的元素
String name = field.getName(); //获取方法名
String modify = Modifier.toString(field.getModifiers()); // 修饰词
String classType = field.getType().getSimpleName(); // 类型
Annotation[] annoArray = field.getAnnotations(); // 注解
field.setAccessible(true); //获取value要赋予权限
Object obj = clazz.newInstance(); //对象实例
Object value = field.get(obj);// 私有属性需要获取权限才可以
field.set(obj, value + "-----changed..");// 修改私有属性的值
1 /** 2 * 通过反射机制获取类 的属性名及其内容 3 * @param strName 4 * @throws ClassNotFoundException 5 * @throws InstantiationException 6 * @throws IllegalAccessException 7 */ 8 public void getClassFieldByName(String strName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { 9 String strClass = getClassName(strName); 10 Class<?> clazz = Class.forName(strClass); 11 Object obj = clazz.newInstance(); 12 Field[] fieldArray = clazz.getDeclaredFields(); // 显示所有的属性 13 Field[] publicFieldArray = clazz.getFields(); //显示public属性的元素 14 Field[] newFieldArray = (Field[])ArrayUtils.addAll(fieldArray, publicFieldArray); 15 for(Field field : newFieldArray){ 16 String name = field.getName(); 17 String modify = Modifier.toString(field.getModifiers()); 18 String classType = field.getType().getSimpleName(); 19 Annotation[] annoArray = field.getAnnotations(); 20 String strAnno = ""; 21 for(Annotation anno : annoArray){ 22 strAnno += "@"+anno.annotationType().getSimpleName(); 23 } 24 field.setAccessible(true); 25 Object value = field.get(obj);// 私有属性需要获取权限才可以 26 System.out.println("propertyName: " + strAnno + " " + modify+ " " + classType + " " + name + "=" + value); 27 if(!StringUtils.contains(modify, "final")){ 28 field.set(obj, value + "-----changed..");// 修改私有属性的值 29 System.out.println("propertyName: " + strAnno + " " + modify+ " " + classType + " " + name + "=" + value); 30 } 31 } 32 33 Field[] fieldsArray = clazz.getSuperclass().getDeclaredFields();//父类的属性名 34 for(Field field : fieldsArray){ 35 String name = field.getName(); 36 String modify = Modifier.toString(field.getModifiers()); 37 String classType = field.getType().getSimpleName(); 38 field.setAccessible(true); 39 Object value = field.get(obj);// 私有属性需要获取权限才可以 40 System.out.println("superPropertyName: " + modify+ " " + classType + " " + name + "=" + value); 41 } 42 }
>>> reflectFactory.getClassFieldByName("rabit");
运行结果:
propertyName: private String rabitName=I am rabit
propertyName: private String rabitName=I am rabit
propertyName: private String header=
propertyName: private String header=
propertyName: private static final int LEGS=4
propertyName: @Resource public String tails=1tails
propertyName: @Resource public String tails=1tails
propertyName: @Resource public String tails=1tails-----changed..
propertyName: @Resource public String tails=1tails-----changed..
superPropertyName: private static final long serialVersionUID=8482086762730882629
superPropertyName: private int slegs=0
superPropertyName: private int shands=0
superPropertyName: private int sheader=0
4. 获取方法,及方法调用
String modifier = Modifier.toString(method.getModifiers()); //修饰词
String returnType = method.getReturnType().getSimpleName();//返回类型
String name = method.getName();//方法名
Parameter[] parameters = method.getParameters();//参数列表
Annotation[] annoArray = method.getAnnotations();//注解列表
Method method = clazz.getMethod(methodName, classes); //根据方法名,获取方法
method.invoke(obj, orgs); //方法调用 注意invoke的第一个参数为方法对应的类的实例。
UserDTO dto = new UserDTO(); dto.setId("12323344"); System.out.println(dto.getClass().getMethod("getId").invoke(dto));
1 /** 2 * 获取方法并调用方法 3 * @param strName 4 * @param methodName 5 * @param orgs 6 * @param classes 7 * @throws ClassNotFoundException 8 * @throws InstantiationException 9 * @throws IllegalAccessException 10 * @throws NoSuchMethodException 11 * @throws SecurityException 12 * @throws IllegalArgumentException 13 * @throws InvocationTargetException 14 */ 15 public void getRunMethodByMethodName(String strName, String methodName, Object[] orgs, Class<?>[] classes) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { 16 String strClass = getClassName(strName); 17 Class<?> clazz = Class.forName(strClass); 18 Class<?> superClazz = clazz.getSuperclass(); 19 Object obj = clazz.newInstance(); 20 Method[] methodArray = clazz.getDeclaredMethods(); 21 Method[] supeMethodArray = superClazz.getDeclaredMethods(); 22 Method[] sumMethodArray = (Method[])ArrayUtils.addAll(methodArray, supeMethodArray); 23 for(Method method : sumMethodArray){ 24 String modifier = Modifier.toString(method.getModifiers()); 25 String returnType = method.getReturnType().getSimpleName(); 26 String name = method.getName(); 27 Parameter[] parameters = method.getParameters(); 28 Annotation[] annoArray = method.getAnnotations(); 29 String strAnno = ""; 30 for(Annotation anno : annoArray){ 31 strAnno += "@"+anno.annotationType().getSimpleName(); 32 } 33 String strPara = ""; 34 for(Parameter para : parameters){ 35 strPara+=para.getType().getSimpleName() + " " + para.getName() + ","; 36 } 37 System.out.println("method:----"+strAnno + " " + modifier + " " + returnType + " " + name + "(" + strPara +")"); 38 } 39 Method method = clazz.getMethod(methodName, classes); 40 System.out.println("header: " + method.invoke(obj, orgs)); 41 }
>>> Class<?>[] classArray = {String.class,int.class,String.class};
>>> Object[] paramsArray = {"兔子只有",1,"头"};
>>> reflectFactory.getRunMethodByMethodName("rabit", "getHeader",paramsArray, classArray);
运行结果:
method:---- public String getHeader()
method:---- public String getHeader(String arg0,int arg1,String arg2,)
method:---- public int getLegs()
method:---- public int getLegs()
header: 兔子只有$$$$1@@@@@@头
5. 构造体方法
clazz.getConstructors() // 获取所有的构造体
----------------------------------------------------------------------------------------------------------
以上,为个人总结,如有写的不当之处,还望指正。
-----------DennyZhao