'); } '); } 配置文件反射加载类和执行函数 | Journey to paradise

配置文件反射加载类和执行函数


配置文件反射加载类和执行函数

利用反射技术和读配置文件的方式实现动态加载类和执行函数

不改变主程序的代码,通过修改配置文件来控制程序的执行,使程序的执行更加灵活。其中properties配置文件的读取写入是根据哈希表执行的,而在现实生活中常常需要顺序读写配置文件,因此需要覆写Properties类,使其顺序读写配置文件。

覆写Properties类,顺序读写配置文件

    package exercise;
    import java.util.Collections;
    import java.util.Enumeration;
    import java.util.LinkedHashSet;
    import java.util.Properties;
    import java.util.Set; 
    /**
    * 用于指定properites文件的存储顺序和输入顺序一样,使得顺序不发生改变
    * OrderedProperties
    */
    public class OrderedProperties extends Properties {
    
        private static final long serialVersionUID = -4627607243846121965L;
    
        private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>();
    
        public Enumeration<Object> keys() {
            return Collections.<Object> enumeration(keys);
        }
    
        public Object put(Object key, Object value) {
            keys.add(key);
            return super.put(key, value);
        }
        
        public synchronized Object remove(Object key) {
            keys.remove(key);
            return super.remove(key);
        }
        
        public Set<Object> keySet() {
            return keys;
        }
    
        public Set<String> stringPropertyNames() {
            Set<String> set = new LinkedHashSet<String>();
    
            for (Object key : this.keys) {
                set.add((String) key);
            }
    
            return set;
        }
    }

测试代码

    package exercise;

    import java.io.File;
    import java.io.FileInputStream;
    import java.lang.reflect.Method;
    import java.util.Iterator;
    import java.util.Properties;

    public class TestDemo {

        public static void main(String[] args) {
            
            Class<?> c1 = null ;
            String strClassName="";
            String strMethodName="";
            
            //Scanner sc = new Scanner(System.in);
            //strClassName = sc.next();
            
            Properties pro = new OrderedProperties();
            File f = new File("Person.properties");
            
            try {
                String strArgs[]; //存放参数值(字符串)
                String strArgsType[]= {};//存放参数类型(字符串)
                Class[] oArgsType=null;  //存放参数类型对应的class对象
                Object[] oArgs=null; //存放参数值对应的object对象
                Object obj = null;  
                String flag="0";//方法开始标记
                pro.load(new FileInputStream(f));
                Iterator<String> it=pro.stringPropertyNames().iterator();//将properties文件中的所有键存放在迭代器中
                while(it.hasNext()){              //判断key的类型并取出相应的值存放在相应变量中
                    String key=it.next();             
                    if(key.equals("class"))
                    {
                        strClassName =pro.getProperty(key);
                        c1 = Class.forName(strClassName) ;               	
                        obj = c1.getConstructor().newInstance();
                    }
                    if(key.substring(0, 1).equals("f"))
                    {
                        flag = pro.getProperty(key);
                    }
                    if(key.subSequence(0, 1).equals("m"))
                    {
                        strMethodName = pro.getProperty(key);          	
                    }
                    if(key.substring(0, 1).equals("k"))
                    {
                        strArgsType= pro.getProperty(key).split(","); //通过,拆分参数类型(字符串)并保存在数组中
                        oArgsType = new Class[strArgsType.length]; 
                        for (int i = 0; i < strArgsType.length; i++) {  //将所有类型字符串分别转换成Class对象
                            oArgsType[i] = getPrimitiveClass(strArgsType[i]);
    //                        System.out.println(oArgsType[i].getName());
                        }               
                    }
                    if(key.substring(0, 1).equals("v"))
                    {
                        strArgs= pro.getProperty(key).split(",");//通过,拆分参数值(字符串)并保存在数组中
                        oArgs = new Object[strArgs.length];         
                        for (int i = 0; i < strArgs.length; i++) { //将所有参数值字符串分别转换成相应的数据类型并转成object对象
                            oArgs[i] = transferArguments(strArgsType[i], strArgs[i]);
    //                        System.out.println(oArgs[i]);
                        }
                    }
                    if(key.substring(0, 1).equals("e")) //判断方法是否结束
                    {
                        Method met;
                        if(flag.equals("1"))
                        {
                            if(oArgsType!=null)//若方法中参数不为空则反射调用有参函数
                            {
                                met= c1.getMethod(strMethodName, oArgsType);
                                met.invoke(obj, oArgs);
                                oArgsType = null;
                                oArgs = null;
                            }
                            else                //否则,反射调用无参函数
                            {
                                met = c1.getMethod(strMethodName);
                                met.invoke(obj);
                            }
                        }
                    }
                
                }
            
                
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } 
        }
        private static Object transferArguments(String type, String value) {//将数据类型字符串转成相应的值(invoke方法中要接收参数值)
            type = type.toLowerCase();
            switch (type) {
                case "int":
                    return Integer.valueOf(value);
                case "double":
                    return Double.valueOf(value);
                case "float":
                    return Float.valueOf(value);
                case "char":
                    return (char)value.getBytes()[0];
                case "string":
                    return value;
                default:
                    System.out.println("undefined!");
                    return null;
            }
        }
        private static Class getPrimitiveClass(String str) {//将数据类型转换成相应的class对象(getmethod方法中参数需要接收class对象)
            str = str.toLowerCase();
            switch (str) {
                case "int":
                    return int.class;
                case "double":
                    return double.class;
                case "float":
                    return float.class;
                case "char":
                    return char.class;
                case "string":
                    return String.class;
                default:
                    System.out.println("undefined!");
                    return Object.class;
            }
        }
        

    }

测试类Person(测试类可根据需求写):
    package exercise;
    public class Person {
        
        public void sayHello(String name,int age) {//有参方法
            System.out.println("Hello "+ ",I'm"+name+", "+age);
        }
        public void print() {//无参方法
            System.out.println("This is print function");
        }
    }

Person类的properties文件(Properties文件可以自己写,也可以通过程序生成,这里就自己写了):
    s1=1                   
    class=exercise.Person    ##class类包路径  
    f1=1                              ##f标记方法开始
    m1=sayHello               ##m方法名
    k1=String,int                ##k参数类型
    v1=Lily,18                    ##v参数值
    e1=1                            ##e标记方法结束
    f2=1
    m2=print
    e2=1

文章作者: 涂爽
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 涂爽 !
评论
 上一篇
this关键字 this关键字
Java中的this关键字 示例一 要点 关于java语言当中的this关键字: 1、this是一个关键字, 翻译为:这个 2、this是一个引用,this是一个
2021-08-06
下一篇 
数据信息的表示 数据信息的表示
数据信息的表示        数据表示是指在计算机中能被硬件直接识别和处理的数据类型,而能被硬件直接识别和处理是指在计算机系统的指令集中包含对这些类型的
  目录