Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:对依赖类的两个不同版本使用相同的代码_Java - Fatal编程技术网

Java:对依赖类的两个不同版本使用相同的代码

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

考虑一个使用库栏的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);
    }
}
公共类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");
        }
}
这很难看,而且速度较慢,使用反射就是它的目的。

我假设:

  • 不能更改任何Bar类文件的版本
  • 您可以编写新的Foo文件
  • 出于某种原因,您确实希望避免使用反射
  • 这两个Bar文件具有相同的包名
  • 您可能需要分发两个版本的Foo类,正如JB Nizet在对您的问题的评论中提到的那样。

    我假设:

  • 不能更改任何Bar类文件的版本
  • 您可以编写新的Foo文件
  • 出于某种原因,您确实希望避免使用反射
  • 这两个Bar文件具有相同的包名
  • 您可能需要分发两个版本的Foo类,正如JB Nizet在对您的问题的评论中提到的那样。

    我假设:

  • 不能更改任何Bar类文件的版本
  • 您可以编写新的Foo文件
  • 出于某种原因,您确实希望避免使用反射
  • 这两个Bar文件具有相同的包名
  • 您可能需要分发两个版本的Foo类,正如JB Nizet在对您的问题的评论中提到的那样。

    我假设:

  • 不能更改任何Bar类文件的版本
  • 您可以编写新的Foo文件
  • 出于某种原因,您确实希望避免使用反射
  • 这两个Bar文件具有相同的包名

  • 您可能需要分发两个版本的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
    或者如果您已经有bar
    c=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(“应该是静态的”);
    继续;
    }
    类参数[