【问题标题】:Casting generic return type to interface type将泛型返回类型转换为接口类型
【发布时间】:2013-10-17 08:19:47
【问题描述】:

我正在尝试为通用包装器创建工厂方法,但我遇到的问题是我需要传入所需的返回类型(wrapTyped() 方法),或者我必须将输入参数显式转换为所需的返回类型(wrapAuto()-方法,第一次使用)。但我 懒惰,不想写额外的演员表 :)

有没有什么方法可以表达 wrapAuto() 的声明,以便“wantThis”(在最底部)的情况有效?

public class GenericFactory {

static class Wrapper<T> {
    T wrappdObject;
    boolean flag;
    String name;

    public Wrapper(T wrappedObject, boolean flag, String name) {
        this.wrappdObject = wrappedObject;
        this.flag = flag;
        this.name = name;
    }

    public T getObject() {
        return wrappdObject;
    }

    // some more irrelevant methods
}

static interface InterfaceType {
}

static class ImplementationA implements InterfaceType {
}

static <U> Wrapper<U> wrapTyped(Class<U> type, U wrappedObject, boolean flag, String name) { 
    return new Wrapper<U>(wrappedObject, flag, name);
}

static <U> Wrapper<U> wrapAuto(U wrappedObject, boolean flag, String name) {
    return new Wrapper<U>(wrappedObject, flag, "NoName");
}

// compiles, but is cumbersome
public Wrapper<InterfaceType> cumbersome = wrapTyped(InterfaceType.class, new ImplementationA(), true, "A");

// compiles, but is also cumbersome
public Wrapper<InterfaceType> alsoUgly = wrapAuto((InterfaceType) new ImplementationA(), true, "B");

// Want this, but "Type mismatch error"
public Wrapper<InterfaceType> wantThis = wrapAuto(new ImplementationA(), false, "C");

}

我把它剥离了一点,为了简单起见,我只声明了一组接口和具体实现。我练习了 Wrapper 类可以用于许多完全不同的、不相关的类型。

【问题讨论】:

    标签: java generics


    【解决方案1】:

    在您的方法wrapAuto中,添加另一个类型参数,以U为上限,并将其用作形参类型:

    static <U, T extends U> Wrapper<U> wrapAuto(T wrappedObject, boolean flag, String name) {
        return new Wrapper<U>(wrappedObject, flag, "NoName");
    }
    

    然后这会起作用:

    Wrapper<InterfaceType> wantThis = wrapAuto(new ImplementationA(), false, "C");
    

    通过此调用,T 被推断为ImplementationA,U 被推断为InterfaceType。并且边界T extends U 完美匹配这些类型。


    参考资料:

    【讨论】:

    • 哇,漂亮又简单。甚至 Wrapper n = wrapAuto(7, ...);现在就像一个魅力。
    • 开始方法的签名没有问题。这是一个推理问题。我不认为在方法中添加额外的不必要的类型参数是处理它的好方法。
    【解决方案2】:

    您所写的方法没有任何问题。但推理并不完美。您始终可以显式指定类型参数:

    public Wrapper<InterfaceType> wantThis = GenericFactory.<InterfaceType>wrapAuto(new ImplementationA(), false, "C");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 2016-10-20
      • 2023-03-22
      • 2016-10-16
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多