简体   繁体   English

从Java中的泛型方法调用重载方法

[英]Calling overloaded methods from generic method in Java

I have a list of Foo and Bar objects, and a converter for each of the corresponding ones. 我有一个Foo和Bar对象的列表,以及每个对应对象的转换器。

public static void Convert(Foo1 a, Bar1 b) {
...
}
public static void Convert(Foo2 a, Bar2 b) {
...
}
etc

Some of the objects, however, contains lists. 但是,某些对象包含列表。
The Convert-methods needs to be different, because Bar1 is vastly different from Bar2 and Bar3 and so on, but I want to create one method to handle all possible lists. 转换方法需要有所不同,因为Bar1与Bar2和Bar3等存在很大差异,但是我想创建一种方法来处理所有可能的列表。

Is it possible to create a generic method that calls the appropriate non-generic method depending on the contents of the list? 是否可以创建一个泛型方法,以根据列表的内容调用适当的非泛型方法?

So far I've tried this: 到目前为止,我已经尝试过了:

public static <T, S> void ConvertList(List<T> list, List<S> libList) {
    list = new ArrayList<T>(libList.size());

    for (int i = 0; i < libList.size(); ++i) {
        Convert(list.get(i), libList.get(i));
    }
}

But that doesn't compile because "Cannot resolve method 'Convert(T,S)'" 但这不能编译,因为“无法解析方法'Convert(T,S)'”

Any ideas? 有任何想法吗?

No, you can't do this - overloading is determined at compile-time , and it sounds like you want different methods to be called based on either the execution-time type of the objects involved, or at least on the execution-time type of T , which is completely unknown at execution time. 不,您不能这样做-重载是在编译时确定的,这听起来像您希望基于所涉及对象的执行时类型或至少根据执行时类型来调用不同的方法T ,在执行时完全未知。

Code-path decisions based on execution-time type are usually handled via overriding via overloading, but it's not clear whether this is feasible in this case. 基于执行时间类型的代码路径决策通常是通过重载进行覆盖来处理的,但尚不清楚在这种情况下这是否可行。 If you could put an appropriate convert method in each Foo?? 如果可以在每个Foo??放置适当的convert方法Foo?? subclass, you could potentially constrain T and S accordingly, but basically there's too much context we're unaware of at the moment. 子类,您可能会相应地约束TS ,但基本上,目前我们尚不了解太多上下文。

You could use reflection to find and invoke the most appropriate method at execution time, but that's going to be painful to code and potentially significantly slower. 可以在执行时使用反射来查找和调用最合适的方法,但这会给代码带来痛苦,并且可能会大大降低速度。

You will have to use runtime polymorphism to achieve this. 您将必须使用运行时多态来实现此目的。

Step 1: Create interfaces representing each type. 步骤1:创建代表每种类型的接口。

public  interface Foo<T> {
    public void convert(T bar);
}
public interface Bar<T> {
    public void convert(T foo);
}

Step 2: create implementation classes. 步骤2:创建实施类。

public class Foo1 implements Foo<Bar1> {

    @Override
    public void convert(Bar1 bar) {
        System.out.println("Foo1, Bar1");
    }
}
public public class Bar1 implements Bar<Foo1> {

    @Override
    public void convert(Foo1 foo) {
        System.out.println("Foo1, Bar1");
    }
}
public class Foo2 implements Foo<Bar2> {

    @Override
    public void convert(Bar2 bar) {
        System.out.println("Foo2, Bar2");
    }
}
public class Bar2 implements Bar<Foo2> {

    @Override
    public void convert(Foo2 foo) {
        System.out.println("Foo2, Bar2");
    }
}

Step 3: Create function which calls convert method according to instances in the list. 步骤3:创建函数,该函数根据列表中的实例调用convert方法。

public static <T extends Foo, S extends Bar> void convertList(List<T> list,
        List<S> libList) {

    for (int i = 0; i < libList.size(); ++i) {
        list.get(i).convert(libList.get(i));
    }
}

Step 4: Create Sample list data and test it 步骤4:创建样本列表数据并对其进行测试

    List<Foo<?>> listOfFoos = new ArrayList<Foo<?>>();
    List<Bar<?>> listOfBars = new ArrayList<Bar<?>>();
    listOfFoos.add(new Foo1());
    listOfFoos.add(new Foo2());
    listOfBars.add(new Bar1());
    listOfBars.add(new Bar2());
    convertList(listOfFoos,listOfBars);

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM