考虑使用库 Bar 的Java类 Foo 。 Foo 应作为二进制.class文件分发,并使用已存在于客户端类路径中的 Bar 版本。
有两种不同版本的 Bar 只在方法签名上有所不同。 Foo 应与这两者兼容。
示例代码:
public class Foo {
public static void main(String[] args){
Bar.librarycall("hello from foo");
//or
Bar.librarycall("hello from foo",1);
}
}
//v1
public class Bar {
public static void librarycall(String argument){
System.out.println("Bar1: " + argument);
}
}
//v2
public class Bar {
public static void librarycall(String argument,int i){
for(int j = 0; j < i; j++)
System.out.println("Bar2: " + argument);
}
}
如果可能,我想避免反思。您如何建议创建一个与 Bar 的两个版本兼容的类 Foo ?
[编辑]
这个问题起源于我正在研究的项目。 Bar 对应我正在使用的外部库但无法修改代码才能工作(我没有源代码,许可证也不允许修改)。
答案 0 :(得分:1)
反射似乎是最简单的方法。另一种方法是尝试调用第二个版本并捕获NoSuchMethodException
。
public class Foo {
public static void main(String[] args){
try {
Bar.librarycall("hello from foo",1);
catch(NoSuchMethodException e) {
Bar.librarycall("hello from foo");
}
}
这很难看,而且速度较慢,请使用Reflection来实现其目的。
答案 1 :(得分:1)
听起来这是由strategy pattern处理的一项任务。
答案 2 :(得分:1)
反思性解决方案。
Class<?> c;
try {
c = Class.forName("Bar");
Method meths[] = c.getMethods();
Method v1method = null;
Method v2method = null;
for(Method m:meths) {
if(!m.getName().equals("librarycall")) continue;
if(!Modifier.isStatic(m.getModifiers())) {
System.out.println("Should be static");
continue;
}
Class<?> params[] = m.getParameterTypes();
if(params.length == 1 && params[0].equals(String.class) )
v1method = m;
if(params.length == 2 && params[0].equals(String.class) && params[1].equals(Integer.TYPE) )
v2method = m;
}
if(v2method!=null) {
v2method.invoke(null,"V2",5);
}
else if(v1method!=null) {
v1method.invoke(null,"V1");
}
else
System.out.println("No method found");
} catch (ClassNotFoundException e) {
System.out.println(e);
} catch (IllegalArgumentException e) {
System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
} catch (InvocationTargetException e) {
System.out.println(e);
}
您可以使用c = Bar.class;
或者您已经拥有Bar c = bar.getClass()
的实例栏。如果非静态方法需要v1method.invoke(bar,"V1");
。
答案 3 :(得分:0)
我假设:
您可能需要分发两个版本的Foo类,如JB Nizet在您的问题评论中所述。