要实现的功能是:手机用户通过GPRS打开Socket与服务器连接,我则根据用户传过来的数据做出响应。
首先定义一个接口来隔离类:package org.bromon.reflect;public interface Operator{
       public java.util.List act(java.util.List params)
}根据设计模式的原理,我们可以为不同的功能编写不同的类,每个类都继承Operator接口,客户端只需要针对Operator接口编程就可以避免很多麻烦。比如这个类:package org.bromon.reflect.*;public class Success implements Operator{
       public java.util.List act(java.util.List params)       {              List result=new ArrayList();              result.add(new String(“操作成功”));              return result;       }}
我们还可以写其他很多类,但是有个问题,接口是无法实例化的,我们必须手动控制具体实例化哪个类,这很不爽,如果能够向应用程序传递一个参数,让自己去选择实例化一个类,执行它的act方法,那我们的工作就轻松多了。编写一个配置文件emp.properties:
#成功响应1000=Success#向客户发送普通文本消息2000=Load#客户向服务器发送普通文本消息3000=Store
文件中的键名是客户将发给我的消息头,客户发送1000给我,那么我就执行Success类的act方法,类似的如果发送2000给我,那就执行Load类的act方法,这样一来系统就完全符合开闭原则了,如果要添加新的功能,完全不需要修改已有代码,只需要在配置文件中添加对应规则,然后编写新的类,实现act方法就ok,即使我弃这个项目而去,它将来也可以很好的扩展。这样的系统具备了非常良好的扩展性和可插入性。
下面的代码要体现了动态加载的功能,程序在执行过程中才知道应该实例化哪个类:package org.bromon.reflect.*;import java.lang.reflect.*;public class TestReflect{
       //加载配置文件,查询消息头对应的类名       private String loadProtocal(String header)    {        String result=null;       try       {           Properties prop=new Properties();           FileInputStream fis=new FileInputStream("emp.properties");           prop.load(fis);           result=prop.getProperty(header);           fis.close();        }catch(Exception e)       {           System.out.println(e);       }        return result;    }    //针对消息作出响应,利用反射导入对应的类    public String response(String header,String content)    {        String result=null;        String s=null;       try        {           /*            * 导入属性文件emp.properties,查询header所对应的类的名字
            * 通过反射机制动态加载匹配的类,所有的类都被Operator接口隔离
            * 可以通过修改属性文件、添加新的类(继承MsgOperator接口)来扩展协议
            */           s="org.bromon.reflect."+this.loadProtocal(header);           //加载类          Class c=Class.forName(s);           //创建类的事例           Operator mo=(Operator)c.newInstance();           //构造参数列表           Class params[]=new Class[1];           params[0]=Class.forName("java.util.List");           //查询act方法           Method m=c.getMethod("act",params);           Object args[]=new Object[1];           args[0]=content;           //调用方法并且获得返回           Object returnObject=m.invoke(mo,args);        }catch(Exception e)       {           System.out.println("Handler-response:"+e);       }        return result;    }    public static void main(String args[])    {        TestReflect tr=new TestReflect();       tr.response(args[0],”消息内容”);    }}
测试一下:java TestReflect 1000 (想得到的结果)
     这个程序是针对Operator编程的,所以应该无需做任何修改,直接提供Load和Store类,就可以支持2000、3000做参数的调用。
请问Operator.class , Success.class 和配置文件emp.properties应该放在什么目录下>才能使程序运行成功?谢谢

解决方案 »

  1.   

    放到classpath就可以 有问题??
      

  2.   

    编译不通过 说是接口Operator有问题不知道什么地方错了。。
      

  3.   

    public interface Operator{
        public java.util.List act(java.util.List params)
    }
    方法声明少了分号了吧
    另外方法声明前可以不要写public
      

  4.   

    to loveyt(咆哮的独角兽) :
    谢谢 这点我也发现了
    修改之后仍然出现点问题:在编译Success.java时出现提示:
    Success.java:1: <identifier> expected
    package org.reflect.*;在编译TestReflect.java时,提示:
    TestReflect.java:95: cannot find symbol
    symbol  : class Operator
    location: class org.reflect.TestReflect
               Operator mo=(Operator)c.newInstance();
      

  5.   

    cannot find symbol提示是因为找不到类的定义。看看是不是把Operator导入进来了
      

  6.   

    对了,package不能写package org.bromon.reflect.*;之类的,可以写import package org.bromon.reflect.*;打包只能写到具体的包,不能加*号。
      

  7.   

    怎么测试Operator接口是否已经导入呢?
      

  8.   

    修改后的代码如下://Operator.javapackage org.bromon.reflect;public interface Operator{       public java.util.List act(java.util.List params);}-------------------------------------------------------------------------------//Success.javapackage org.bromon.reflect;import java.util.*;
    public class Success implements Operator{       public java.util.List act(java.util.List params)
           {              List result=new ArrayList();              result.add(new String("操作成功"));              return result;       }}-----------------------------------------------------------------------------------//emp.properties#成功响应1000=Success#向客户发送普通文本消息2000=Load#客户向服务器发送普通文本消息3000=Store--------------------------------------------------------------------------//Testreflect.javaimport org.bromon.reflect.Operator;import java.util.*;import java.lang.reflect.*;import java.io.*;public class TestReflect
    {
           //加载配置文件,查询消息头对应的类名
           private String loadProtocal(String header)
        {
            String result=null;
           try       {           Properties prop=new Properties();           FileInputStream fis=new FileInputStream("emp.properties");
               prop.load(fis);
               result=prop.getProperty(header);
               fis.close();
            }catch(Exception e)       {           System.out.println(e);       }        return result;
        }    //针对消息作出响应,利用反射导入对应的类    public String response(String header,String content)    {        String result=null;        String s=null;       try        {
              
               s="org.bromon.reflect."+this.loadProtocal(header);           //加载类           Class c=Class.forName(s);           //创建类的事例           Operator mo=(Operator)c.newInstance();           //构造参数列表           Class params[]=new Class[1];           params[0]=Class.forName("java.util.List");           //查询act方法           Method m=c.getMethod("act",params);           Object args[]=new Object[1];
               args[0]=content;
               //调用方法并且获得返回
               Object returnObject=m.invoke(mo,args);
            }catch(Exception e)
           {           System.out.println("Handler-response:"+e);       }
            return result;
        }
        public static void main(String args[])    {        TestReflect tr = new TestReflect();
            tr.response(args[0],"消息内容");
        }}编译通过,但键入java TestReflect 1000时出现
    Handler-response:java.lang.IllegalArgumentException: argument type mismatch另外编译Success.java时有提示:
    Note: Success.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
      

  9.   

    下面提示是告诉你你使用了不安全的方法操作,你的编译环境应该是JDK1.5,针对以前的JDK版本在安全性方面做了很多改进,但是在JDK1.5环境下出现这个提示不影响程序运行。上面的提示就是错误了。应该是你的参数和需要的类型不一致,贴出具体的异常来看看。
      

  10.   

    键入java TestReflect 时出现异常
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
            at TestReflect.main(TestReflect.java:153)