简体   繁体   English

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

[英]Java: Use the same code with two different versions of a dependent class

Consider a Java class Foo that uses a library Bar . 考虑使用库Bar的Java类Foo Foo should be distributed as a binary .class file and use the version of Bar that is already existing on a clients classpath. Foo应该作为二进制.class文件分发,并使用客户端类路径上已经存在的Bar版本。

There are two different versions of Bar that only differ in its method signatures. Bar有两种不同的版本,只是其方法签名不同。 Foo should be compatible with both of them. Foo应该与它们两者兼容。

Example code: 示例代码:

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);
    }
}

I want to avoid reflection if possible. 如果可能,我要避免反射。 How would you propose to create a class Foo that is compatible with both versions of Bar ? 您如何建议创建一个与Bar的两个版本都兼容的Foo类?

[Edit] [编辑]

This problem originates in a project I am working on. 此问题源于我正在从事的项目。 Bar corresponds to an external library I am using but cannot be modified for the code to work (I don't have the source code and the license doesn't allow modifications). Bar对应于我正在使用的外部库,但无法对其进行修改以使代码正常工作(我没有源代码,并且许可证不允许进行修改)。

Reflection does seem like the simplest way. 反射似乎是最简单的方法。 The alternative would be to try calling the second version and catch a NoSuchMethodException . 另一种方法是尝试调用第二个版本并捕获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");
        }
}

This is ugly, and slower, use Reflection its what its there for. 这很丑陋,而且速度较慢,请使用Reflection及其功能。

听起来这是一项由策略模式处理的任务。

A refelective solution. 一种折衷的解决方案。

    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);
    }

You could use c = Bar.class; 您可以使用c = Bar.class; or if you already have an instance bar of Bar c = bar.getClass() . 或如果您已经具有Bar c = bar.getClass()的实例栏。 The invoke syntax is for static methods if its non static you need v1method.invoke(bar,"V1"); 如果非静态方法需要v1method.invoke(bar,"V1");则调用语法适用于静态方法v1method.invoke(bar,"V1"); .

I'm assuming that: 我假设:

  1. You cannot change any of the versions of the Bar class files 您不能更改Bar类文件的任何版本
  2. You have the ability to write new Foo files 您可以编写新的Foo文件
  3. For some reason, you really want to avoid using Reflection 由于某些原因,您确实要避免使用Reflection
  4. The two Bar files have the same package name 两个Bar文件具有相同的包名称

You may need to distribute two versions of the Foo class, as mentioned by JB Nizet in the comment to your question. 您可能需要分发Foo类的两个版本,正如JB Nizet在对问题的评论中提到的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 同一Java类的两个版本,每个版本具有不同的超类 - Two versions of the same Java class where each has a different superclass Java - 如何加载同一类的不同版本? - Java - how to load different versions of the same class? 同一 Gradle 项目中不同 Java 版本的代码 - Code for different Java versions in same Gradle Project 如何在同一应用程序中使用不同版本的 class? - How to use different versions of a class in the same application? 我可以在同一个项目上使用两个不同的 Eclipse (IDE java) 版本吗? - Can I use two different Eclipse (IDE java) versions on same project? 允许jar中的两个库使用依赖Java的两个不同版本 - Allowing two libraries in jar to use two different versions of a dependency java 我可以在Java中使用两个不同版本保存相同的jar吗? - Can I keep same jars with two different versions in java? Maven-两个模块可以使用同一库的不同版本 - maven - can two modules use different versions of the same library 类对象的语法突出显示在两个版本的代码中是不同的 - Syntax highlighting of class object is different in two versions of code 如何从java maven项目中的两个不同版本的jar加载类的两个版本? - How to load two versions of a class from two different versions of jars in a java maven project?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM