简体   繁体   中英

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.

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.

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)'"

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.

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?? subclass, you could potentially constrain T and S accordingly, but basically there's too much context we're unaware of at the moment.

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.

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

Step 2: create implementation classes.

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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