Java 泛型接口的行为不符合预期

Java 泛型接口的行为不符合预期,java,generics,Java,Generics,我有一个简单的通用接口 public interface Person<T> { T foo(T other); } 公共接口人{ T foo(T other);; } 还有一节课 public class Data<T extends Person> { public void doSomething(List<T> data){ data.stream().reduce((a, b) -> (T)a

我有一个简单的通用接口

public interface Person<T> {
    T foo(T other);
}
公共接口人{
T foo(T other);;
}
还有一节课

    public class Data<T extends Person> {

      public void doSomething(List<T> data){
         data.stream().reduce((a, b) -> (T)a.foo(b));
      }
  }
公共类数据{
公共无效剂量测定(列表数据){
data.stream().reduce((a,b)->(T)a.foo(b));
}
}
当我在函数
foo
中使用reduce时,它假设返回泛型类型
T
,编译器说它不能返回,因为它是一个错误的返回类型

但是正如您所看到的,方法
foo
获取并返回
T

另外,当我自动完成我的工作空间时
myObj.foo(obj)

我看到返回类型和参数类型是对象类型。
任何人都可以向我解释为什么会发生这种情况,为什么不是从
T
类型?

您必须指定
Person
的通用参数:

public class Data<T extends Person<T>> {
    ...
}
公共类数据{
...
}

或者稍微移动一下泛型,我还不知道泛型参数有什么意义。

您必须指定
Person的泛型参数:

public class Data<T extends Person<T>> {
    ...
}
公共类数据{
...
}

或者稍微移动一下泛型,我还不知道泛型参数有什么意义。

你的问题是你用字母
T
代表两个完全不同的类型参数-
Person
泛型类中的类型参数和
Data
泛型类中的类型参数

这两个参数不是同一个参数——你已经设法用同一个字母来表示这两个参数了。然而,编译器并不混乱;它非常正确地告诉你不能用一个
t
来代替另一个


特别是,您尝试强制转换一个表达式,其类型为
T
,该
foo
返回,对于另一种类型的
T

,您的问题是使用字母
T
代表两个完全不同的类型参数,
Person
泛型类中的类型参数和
Data
泛型类中的类型参数

这两个参数不是同一个参数——你已经设法用同一个字母来表示这两个参数了。然而,编译器并不混乱;它非常正确地告诉你不能用一个
t
来代替另一个


特别是,您尝试将类型为
T
的表达式转换为
foo
返回的另一种类型的
T

您在这里混淆了两个参数<代码>T
输入

public interface Person<T> {
    T foo(T other);
}
定义类型为
Person
的类
Data
的参数,该参数隐式等于
Person

public class Data<T extends Person> {
    public void doSomething(List<T> data) {
        data.stream().reduce((a, b) -> (T)a.foo(b));
    }
}
因此
List
是扩展
Person
的对象列表,方法
foo()
的返回类型为Person-first参数
object
,而
reduce
期望返回类型为
Person

public class Data<T extends Person> {
    public void doSomething(List<T> data) {
        data.stream().reduce((a, b) -> (T)a.foo(b));
    }
}
这个代码与您的代码没有什么不同:

public class Data<E extends Person> {
    public void doSomething(List<E> data) {
        data.stream().reduce((a, b) -> (E)a.foo(b));
    }
}
公共类数据{
公共无效剂量测定(列表数据){
data.stream().reduce((a,b)->(E)a.foo(b));
}
}

您在这里混淆了两个参数<代码>T
输入

public interface Person<T> {
    T foo(T other);
}
定义类型为
Person
的类
Data
的参数,该参数隐式等于
Person

public class Data<T extends Person> {
    public void doSomething(List<T> data) {
        data.stream().reduce((a, b) -> (T)a.foo(b));
    }
}
因此
List
是扩展
Person
的对象列表,方法
foo()
的返回类型为Person-first参数
object
,而
reduce
期望返回类型为
Person

public class Data<T extends Person> {
    public void doSomething(List<T> data) {
        data.stream().reduce((a, b) -> (T)a.foo(b));
    }
}
这个代码与您的代码没有什么不同:

public class Data<E extends Person> {
    public void doSomething(List<E> data) {
        data.stream().reduce((a, b) -> (E)a.foo(b));
    }
}
公共类数据{
公共无效剂量测定(列表数据){
data.stream().reduce((a,b)->(E)a.foo(b));
}
}