关于动态扩展:在运行时载入类和接口动态扩展我们的程序

Kylix_XP 2003-08-07 11:56:36
java中有两种方式可以实现动态扩展:Class.forName()和java.lang.ClassLoader

请看问题所在:
You often need to modify the behaviour of a program based on external data, such as a command-line parameter. If you hard-code a finite set of acceptable parameter values into a program you will have to modify the program whenever you need to add new parameters. The deployment of new versions will become more complex as the number of installed programs increases. If programs need to interpret parameters in order to interoperate (for example, if the parameters are read from network messages), you must ensure that all users upgrade before they can communicate, which becomes very difficult with large user bases.


解决方法:
Take advantage of Java's built-in(内置的) facilities for dynamic loading and linking of code. Dynamically load and instantiate classes of behaviour corresponding to external parameters.

1.Define an interface through which to access the parameterised behaviour
2.Define a naming scheme that maps user-specified parameters to the name of a Java class.
3.Define classes that implement the interface for various parameters, and follow the naming scheme so that they can be found by the parameter-to-name mapping.
4.At run time, given a parameter value, map it to the name of the Java class that performs the required behaviour.
5.Dynamically load that class using the Class.forName method.
6.Instantiate an object of the class using the Class.newInstance method or via a Constructor of the class.
7.Cast the object to the interface you have defined and pass it to the objects that need to use the parameterised behaviour.

你有一个接口,所有的人都可以实现它,那么这个接口派生的类可能会有无数个,而你的程序又不想(也不可能)把这用到的无数个类声明到你的程序里,重新编译,然后重新启动服务器,这时候就需要动态将Class装载进来。只需要动态提供一个类的包路径,就可以执行该类,这样做最大的好处其实就是动态地处理相同接口的代码.JAVA类或者接口通过一个字符串传给程序,即可以用一个字符串的形式来初始化(映射)一个类!
...全文
73 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
relive 2003-08-13
  • 打赏
  • 举报
回复
以JDialog的JDialog(Container c)构造器为例
Class m_classdialog = java.lang.Class.forName("javax.swing.JDialog");
java.lang.reflect.Constructor cons = m_classdialog.getConstructor(new Class[] { Container.class });
Object m_objectdialog = cons.newInstance(new Object[] { parentContainer});
JDialog myDialog = (JDialog) m_objectdialog;
Kylix_XP 2003-08-12
  • 打赏
  • 举报
回复
relive(六道轮回,无想转生)

结合上面的例子,用java.lang.reflect.Constructor怎么把参数传入类呢?
relive 2003-08-12
  • 打赏
  • 举报
回复
你是问问题还是搞扫盲啊??
问问题的话::java.lang.reflect.Constructor
扫盲的话::GZ
Kylix_XP 2003-08-07
  • 打赏
  • 举报
回复
我门先来定义一个接口:
package test;
public interface Shape {
public void draw();
}
接着我们在定义2个实现类
package test;
public class Circle implements shape {
public void draw() {
System.out.println(" circle draw");
}
}

package test;
public class Rectangle implements shape {
public void draw() {
System.out.println("rectangle draw");
}
}

好,准备工作已经做好了,让我们开始吧.
package test;

public MyTest{

public static void main(String args[]){
try{
String strConfigInfo=getConfigInfo();//getCofingInfo();是你的配置信息来源.可以是从
Class cls = Class.forName(strConfigInfo); //文件中读取,也可以来自注册表.
Shape shp = (Shape)cls.newInstance();
shp.draw();
}catch(Exception e){
e.printStackTrace();
}//end try_catch
}//end main
}//end MyTest

说明:1,如果你现在写了个Shape的实现类MyShape,你只要修改一下配置信息,使getConfingInfo()取的信息是你的类的包路径(包含包名在内的类名,如java.io.FileWriter),那么shp.draw();将会调用你所写类中的draw()方法了.

2, 如果您要写插件,这将将是非常有用的技术.(比c++/delphi 中的动态连接库要方便多了.)


问题是:
那如果你要动态加载的类的构造器中有参数怎么办??


67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧