要实现的功能是:手机用户通过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应该放在什么目录下>才能使程序运行成功?谢谢
首先定义一个接口来隔离类: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应该放在什么目录下>才能使程序运行成功?谢谢
public java.util.List act(java.util.List params)
}
方法声明少了分号了吧
另外方法声明前可以不要写public
谢谢 这点我也发现了
修改之后仍然出现点问题:在编译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();
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.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at TestReflect.main(TestReflect.java:153)