个人认为以下两种方法比较可行:
方法1:
今天看nutch的源代码,发现了其中一个很重要的技巧,就是如何在改变一个类的名字的前提下不去影响引用它的类,即在不需要重新编译那些引用他的类的前提下而使得程序可以正常运行! 具体做法是,我们可以引入一个中间类,这个类的作用类似于一个中介,这个类中存在两个map对象,他们的作用是提供一个名字到具体类的名字的映射,具体代码如下:
private static HashMap NAME_TO_CLASS = new HashMap();
private static HashMap CLASS_TO_NAME = new HashMap();
static {
WritableName.setName(NullWritable.class, "null");
WritableName.setName(LongWritable.class, "long");
WritableName.setName(UTF8.class, "UTF8");
WritableName.setName(MD5Hash.class, "MD5Hash");
WritableName.setName(Page.class, "Page");
WritableName.setName(Link.class, "Link");
}
private WritableName() {}
public static synchronized void setName(Class writableClass, String name)
{
CLASS_TO_NAME.put(writableClass, name);
NAME_TO_CLASS.put(name, writableClass);
}
public static synchronized void addName(Class writableClass, String name)
{ NAME_TO_CLASS.put(name, writableClass); }
public static synchronized String getName(Class writableClass) {
String name = (String)CLASS_TO_NAME.get(writableClass);
if (name != null) return name;
return writableClass.getName();
}
public static synchronized Class getClass(String name) throws IOException {
Class writableClass = (Class)NAME_TO_CLASS.get(name);
if (writableClass != null)
return writableClass;
try { return Class.forName(name); }
catch (ClassNotFoundException e)
{ throw new IOException(e.toString()); }
}
这里我们提供了方法实现一个名字到具体类名的映射;我们在其他类中引用另一个类的时候,不要去直接应用那个类的名字,而是通过调用中介类中的方法来引用(获得)这个类的名字,这样当被调用的类被改变的时候,我们只需要改变一下中介类的代码,然后重新编译中介类的代码就可以了!这样就在最小改变原有代码的前提下保证了程序的正常运行! 这种优点在一个类被引用少的时候显示的不是很明显,但是当一个类被多个类多次引用,它要改变名字的时候如果不采用这种方法或者类似的方法就会比较麻烦,你不得不到引用的类中去仔细的查看代码,然后改变被引用类的名字,最后重新编译!
方法2:
使用 Class.forName("ClassName").newInstance();可以达到同样的目的,而且,那个参数字符串从配置文件中读取,而不用硬编码到代码中
但是这个办法需要一定的IO操作;