0

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

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

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

问题是 - 我如何确定这个通用示例的结果类型?有没有可能写出类似的东西typeof(t.g(u))

4

3 回答 3

3

您不能按原样调用t.g(u),因为T它是无界类型。您需要对其进行编译时限制,以便编译器知道哪些方法可用。否则,您将只能调用Object方法,因为编译器唯一可以推断T的就是 extends 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)
    }
}
于 2012-11-22T18:15:25.740 回答
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也是泛型的,则需要在 class 中为其声明一个单独的类型参数C1。或者,您可以声明C1统一处理单个参数化类型(例如,String× StringString):

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

其他变化也是可能的。

于 2012-11-22T18:13:43.233 回答
0

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

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

该方法的返回类型将是 Ginterface 中 g 函数的返回类型

于 2012-11-22T18:13:54.417 回答