![](/img/trans.png)
[英]Two versions of the same Java class where each has a different superclass
[英]Java: Use the same code with two different versions of a dependent class
考虑使用库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对应于我正在使用的外部库,但无法对其进行修改以使代码正常工作(我没有源代码,并且许可证不允许进行修改)。
反射似乎是最简单的方法。 另一种方法是尝试调用第二个版本并捕获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及其功能。
听起来这是一项由策略模式处理的任务。
一种折衷的解决方案。
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");
则调用语法适用于静态方法v1method.invoke(bar,"V1");
。
我假设:
您可能需要分发Foo类的两个版本,正如JB Nizet在对问题的评论中提到的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.