• 反射机制(java)


    反射机制

         反射机制可通过在运行时加载类名而获取类,并对其进行操作。工厂模式,动态代理中较常用到。

         在实际场景中:由于有好多类具有共同的接口样式,而他们又用的不是很频繁,如果在服务器中保有这些类会占用资源空间,如果通过接口指定的方式去加载,用完之后就销毁掉,可节省资源空间,且实现接口编程,扩展性好,代码量也少。打个比方:哺乳动物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     }
    getClassName
    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
    classPath.properties

    >>> 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     }
    getClass

    >>> 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     }
    getClassFieldByName

    >>> 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     }
    getRunMethodByMethodName

    >>> 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

         

  • 相关阅读:
    ios界面布局整理
    android ProGuard 代码混淆实现
    mac版 android破解软件下载安装
    在unix系统下的 .o文件 .a文件 .so文件说明和相互关系
    android中的广播接收实现总结
    用java的jdk 生成android 的jni接口文档
    Android 自定义Application
    android项目中配置NDK自动编译生成so文件
    创建android Notification
    (ios) nsnotification总结
  • 原文地址:https://www.cnblogs.com/DennyZhao/p/7019126.html
Copyright © 2020-2023  润新知