当前位置: 首页 > 知识库问答 >
问题:

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

陈霄
2023-03-14

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

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


Convert-method需要有所不同,因为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));
    }
}

但这并不能编译,因为"无法解析方法'Converts(T, S)'"

有什么想法吗?

共有2个答案

丌官瀚
2023-03-14

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

第一步:创建代表每种类型的接口。

public  interface Foo<T> {
    public void convert(T bar);
}
public interface Bar<T> {
    public void convert(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");
    }
}

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

第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);
席俊达
2023-03-14

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

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

您可以在执行时使用反射来查找和调用最合适的方法,但是这对代码来说是痛苦的,并且可能要慢得多。

 类似资料:
  • 安吉丽卡·兰格(Angelica Langer)在关于仿制药的常见问题解答中说(参见Technicalities.FAQ822): 如果这些方法具有具有不同边界的类型参数,则它们不会重写,因为这些方法的签名不是重写等价的。请记住,类型参数边界是泛型方法签名的一部分。 示例(泛型子类型方法重载泛型超类型方法;不推荐): 我不明白为什么方法在类中重载。据我所知,这应该是一个编译时错误,因为在和中具有相

  • 我一直在尝试泛型,很快我就遇到了一些我无法解释的事情 例如: 我不明白

  • 这怎么可能呢?为什么添加另一个参数会导致方法解析不明确?为什么在第一个例子中它可以区分供应商和对象,而在第二个例子中却不能? 编辑:这使用的是1.8.0_121。这是完整的错误消息:

  • 我正在尝试覆盖子类中从父类继承抽象方法的方法。我正在尝试更改泛型返回类型,但我有点困惑。 基本泛型类: 儿童班: 实施: 我想在其中覆盖参数化方法的子视图类: 这是Eclipse抛出错误消息的地方: 注意类和接口:事件和级别: 以及继承自 的 Model 类 我试图实现的是编写更抽象的代码,因为这些类、接口将被多个类扩展(在我的例子中是不同的视图类型)。这些是抽象类:< code>BaseAdap

  • 来自Java文档:在类C中声明的实例方法m1覆盖在类A中声明的另一个实例方法m2,如果以下所有条件都为真:。。。。。m1的签名是m2签名的子签名(§8.4.2)。 方法m1的签名是方法m2签名的子签名,前提是:m1的签名与m2签名的擦除相同(§4.6)。 是对一个 如果是这样,什么是错的? EDIT1:或者如果我切换通用类型: 这种情况下有什么问题? EDIT2:我知道如何修复它,但我想了解,在这

  • 这是如何编译的: 但这并不是: 它给我以下编译错误: Impl不是抽象的,并且不会覆盖测试中的抽象方法getValue(整数) 错误:名称冲突:Impl中的getValue(T)和测试中的getValue(Integer)具有相同的擦除,但两者都不重写另一个 擦除不能确保t被整数替换吗?那么为什么第二个例子是无效的呢?