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

在Java中从泛型方法调用重载方法,java,generics,overloading,Java,Generics,Overloading,我有一个Foo和Bar对象的列表,以及每个相应对象的转换器 public static void Convert(Foo1 a, Bar1 b) { ... } public static void Convert(Foo2 a, Bar2 b) { ... } etc 但是,有些对象包含列表。 Convert方法需要不同,因为Bar1与Bar2和Bar3等有很大的不同,但是我想创建一个方法来处理所有可能的列表 是否可以创建一个泛型方法,根据列表的内容调用相应的非泛型方法 到目前为止,我已经尝

我有一个Foo和Bar对象的列表,以及每个相应对象的转换器

public static void Convert(Foo1 a, Bar1 b) {
...
}
public static void Convert(Foo2 a, Bar2 b) {
...
}
etc
但是,有些对象包含列表。
Convert方法需要不同,因为Bar1与Bar2和Bar3等有很大的不同,但是我想创建一个方法来处理所有可能的列表

是否可以创建一个泛型方法,根据列表的内容调用相应的非泛型方法

到目前为止,我已经尝试过:

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));
    }
}
publicstaticvoidconvertlist(列表列表,列表libList){
list=newarraylist(libList.size());
对于(int i=0;i
但这不会编译,因为“无法解析方法‘Convert(t,S)’”


有什么想法吗?

您必须使用运行时多态性来实现这一点

步骤1:创建代表每种类型的接口

public  interface Foo<T> {
    public void convert(T bar);
}
public interface Bar<T> {
    public void convert(T foo);
}
公共接口Foo{
公共空间转换(T形杆);
}
公共接口栏{
公共空间转换(T-foo);
}
步骤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");
    }
}
公共类Foo1实现Foo{
@凌驾
公共无效转换(1巴){
System.out.println(“Foo1,Bar1”);
}
}
公共类Bar1实现Bar{
@凌驾
公共无效转换(Foo1 foo){
System.out.println(“Foo1,Bar1”);
}
}
公共类Foo2实现了Foo{
@凌驾
公共空间转换(2巴){
System.out.println(“Foo2,Bar2”);
}
}
公共类Bar2实现了Bar{
@凌驾
公共无效转换(Foo2 foo){
System.out.println(“Foo2,Bar2”);
}
}
步骤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));
    }
}
公共静态无效列表(列表,
列表(libList){
对于(int i=0;i
步骤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);
List>();
列表>();
add(newfoo1());
add(newfoo2());
add(newbar1());
添加(新的Bar2());
convertList(ListofOOS、listOfBars);

您必须使用运行时多态性来实现这一点

步骤1:创建代表每种类型的接口

public  interface Foo<T> {
    public void convert(T bar);
}
public interface Bar<T> {
    public void convert(T foo);
}
公共接口Foo{
公共空间转换(T形杆);
}
公共接口栏{
公共空间转换(T-foo);
}
步骤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");
    }
}
公共类Foo1实现Foo{
@凌驾
公共无效转换(1巴){
System.out.println(“Foo1,Bar1”);
}
}
公共类Bar1实现Bar{
@凌驾
公共无效转换(Foo1 foo){
System.out.println(“Foo1,Bar1”);
}
}
公共类Foo2实现了Foo{
@凌驾
公共空间转换(2巴){
System.out.println(“Foo2,Bar2”);
}
}
公共类Bar2实现了Bar{
@凌驾
公共无效转换(Foo2 foo){
System.out.println(“Foo2,Bar2”);
}
}
步骤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));
    }
}
公共静态无效列表(列表,
列表(libList){
对于(int i=0;i
步骤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);
List>();
列表>();
add(newfoo1());
add(newfoo2());
add(newbar1());
添加(新的Bar2());
convertList(ListofOOS、listOfBars);

不,您不能这样做-重载是在编译时确定的,听起来您希望根据所涉及对象的执行时类型调用不同的方法,或者至少根据执行时完全未知的
t
的执行时类型调用不同的方法

基于执行时间类型的代码路径决策通常通过重载重写来处理,但目前还不清楚这种情况下是否可行。如果您可以在每个
Foo???
子类中放置一个适当的
convert
方法,您可能会相应地约束
T
S
,但基本上我们现在不知道太多的上下文


您可以在执行时使用反射来查找和调用最合适的方法,但这对编写代码来说将是一件痛苦的事情,而且可能会大大降低速度。

不,您不能这样做-重载是在编译时确定的,听起来您希望根据所涉及对象的执行时间类型调用不同的方法,或者至少根据执行时间类型
T
,这在执行时是完全未知的

基于执行时间类型的代码路径决策通常通过重载重写来处理,但目前还不清楚这种情况下是否可行。如果您可以在每个
Foo???
子类中放置一个适当的
convert
方法,您可能会相应地约束
T
S
,但基本上我们现在不知道太多的上下文


您可以在执行时使用反射来查找并调用最合适的方法,但这对编写代码来说是一件痛苦的事情,而且可能会大大降低速度。

除非有
Convert(Foo,Bar)
方法,否则这仍然无法编译,问题中当然没有具体说明。@JonSkeet谢谢。更新了答案。我想现在你可以删除否决票了。不,因为这不能满足传递不同类型的不同列表的能力:“是否可以创建一个泛型方法,根据列表的内容调用相应的非泛型方法?”是,潜在-如果每个Foo只有一个条配对,并且可以修改if
Foo
。这基本上就是我的建议