Java:对依赖类的两个不同版本使用相同的代码
考虑一个使用库栏的Java类Foo。Foo应作为二进制.class文件分发,并使用客户机类路径上已有的Bar版本 Bar有两种不同的版本,它们只在方法签名上有所不同。Foo应该与两者兼容 示例代码:Java:对依赖类的两个不同版本使用相同的代码,java,Java,考虑一个使用库栏的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
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);
}
}
公共类Foo{
公共静态void main(字符串[]args){
Bar.librarycall(“来自foo的你好”);
//或
Bar.librarycall(“来自foo的你好”,1);
}
}
//v1
公共类酒吧{
公共静态void librarycall(字符串参数){
System.out.println(“Bar1:+参数);
}
}
//v2
公共类酒吧{
公共静态void librarycall(字符串参数,int i){
对于(int j=0;j
如果可能的话,我想避免反思。您打算如何创建一个与两个版本的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");
}
}
这很难看,而且速度较慢,使用反射就是它的目的。反射似乎是最简单的方法。另一种方法是尝试调用第二个版本并捕获
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");
}
}
这很难看,而且速度较慢,使用反射就是它的目的。反射似乎是最简单的方法。另一种方法是尝试调用第二个版本并捕获
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");
}
}
这很难看,而且速度较慢,使用反射就是它的目的。反射似乎是最简单的方法。另一种方法是尝试调用第二个版本并捕获
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");
}
}
这很难看,而且速度较慢,使用反射就是它的目的。我假设:
您可能需要分发两个版本的Foo类,正如JB Nizet在对您的问题的评论中所提到的。这听起来像是由处理的任务。这听起来像是由处理的任务。这听起来像是由处理的任务。这是一个参考方案
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类;
试一试{
c=类别forName(“Bar”);
方法meths[]=c.getMethods();
方法v1method=null;
方法v2method=null;
用于(方法m:方法){
如果(!m.getName().equals(“librarycall”))继续;
if(!Modifier.isStatic(m.getModifiers())){
System.out.println(“应该是静态的”);
继续;
}
类params[]=m.getParameterTypes();
如果(params.length==1&¶ms[0]=String.class))
v1方法=m;
if(params.length==2&¶ms[0].equals(String.class)&¶ms[1].equals(Integer.TYPE))
v2方法=m;
}
if(v2method!=null){
v2method.invoke(null,“V2”,5);
}
else if(v1方法!=null){
V1方法调用(null,“V1”);
}
其他的
System.out.println(“未找到方法”);
}catch(classnotfounde异常){
系统输出打印ln(e);
}捕获(IllegalArgumentException e){
系统输出打印ln(e);
}捕获(非法访问例外e){
系统输出打印ln(e);
}捕获(调用TargetException e){
系统输出打印ln(e);
}
您可以使用
c=Bar.class
或者如果您已经有barc=bar.getClass()
的实例栏。如果您需要非静态的v1method.invoke(bar,“V1”)代码>一种可供参考的解决方案
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类;
试一试{
c=类别forName(“Bar”);
方法meths[]=c.getMethods();
方法v1method=null;
方法v2method=null;
用于(方法m:方法){
如果(!m.getName().equals(“librarycall”))继续;
if(!Modifier.isStatic(m.getModifiers())){
System.out.println(“应该是静态的”);
继续;
}
类参数[