Java通用操作结果类型

时间:2012-11-22 18:09:48

标签: java templates generics types

我不是专业的Java程序员,所以这个问题可能很简单,但我已经在网上搜索了答案,但到目前为止一无所获。

假设我们在Java中有一个泛型类:

public class C1 <T, U> {
  public /*TYPE*/ f(T t, U u) {  
    return t.g(u)
  }

问题是 - 如何确定此通用示例的结果类型? 是否有可能写出类似typeof(t.g(u))的内容?

3 个答案:

答案 0 :(得分:3)

您不能按原样拨打t.g(u),因为T是无限制类型。您需要在其上放置编译时绑定,以便编译器知道可用的方法。否则,您将只能调用Object方法,因为编译器可以推断T的唯一内容是扩展Object

例如,如果您的接口G<U>包含您要调用的g方法:

public interface G<U> {
    R g(U u);
}

然后,您可以指定T extends G<U>,以便拨打g()。现在您知道g()的返回类型是什么:它是R

public class C1<T extends G<U>, U> {
    public R f(T t, U u) {  
        return t.g(u)
    }
}

如果您希望g()的结果依赖于类型TU,那么您可以执行以下操作:

public interface G<T, U> {
    T g(U u);
}

public class C1<T, U> {
    public T f(G<T, U> g, U u) {  
        return g.g(u)
    }
}

答案 1 :(得分:2)

您的代码不会按原样编译,因为没有什么可以告诉编译器t有一个成员函数g。您需要将类型参数T声明为扩展某些基类或接口,确实声明了g()方法。返回类型将是g的返回类型(可能是另一种参数类型)。

例如:

public interface Foo<X, Y> {
    X g(Y u);
}

public class C1 <T extends Foo<X, U>, U, X> {
    public X f(T t, U u) {  
        return t.g(u);
    }
}

请注意,如果返回类型X也是通用的,则需要在类C1中为它声明一个单独的类型参数。或者,您可以声明C1统一处理单个参数化类型(例如,String×StringString):

public class C1 <T extends Foo<T, T>> {
    public T f(T t, T u) {  
        return t.g(u);
    }
}

其他变化也是可能的。

答案 2 :(得分:0)

如果你想强制执行方法g,你必须像这样声明你的类:

public class C1<T extends Ginterface, U extends SecInterface> {
}

,此方法的返回类型将是Ginterface

中g函数的返回类型