你能否解释一下为什么以下工作方式呢? 在我看来,java类型系统很难推断R的类型
public class Test {
interface Parser<A,R>{
R parse(A a);
}
static class ResponseParser implements Parser<String,Integer>{
public Integer parse(String s) {
return Integer.parseInt(s) + 1;
}
}
interface Function<A,R>{
R with(A a);
}
public static <A,R,P extends Parser<A,R>> Function<P,R> getResult(final A res){
return new Function<P, R>() {
public R with(P parser) {
return parser.parse(res);
}
};
}
public static void main(String [] args){
Function<Parser<String,Integer>, Integer> func = getResult("1");
//this works
func.with(new ResponseParser());
// why this does not work
getResult("1").with(new ResponseParser());
}
}
答案 0 :(得分:4)
在getResult("1").with(new ResponseParser());
表达式中,无法从上下文中正确推断出getResult("1")
子表达式的类型。您认为它应该是Function<? extends Parser<String, Integer>, Integer>
,但此子表达式对Integer
一无所知。在第一种情况下,您将结果分配给Function<Parser<String,Integer>, Integer>
,因此可以解析R = Integer
类型,但是当您只是调用其他方法时,它就无法正常工作。
你可以解决这个推迟推断返回类型的必要性。像这样:
interface ParserFunction<A> {
<R> R with(Parser<A, R> a);
}
public static <A> ParserFunction<A> getResult(final A res){
return new ParserFunction<A>() {
public <R> R with(Parser<A, R> parser) {
return parser.parse(res);
}
};
}
现在getResult("1").with(new ResponseParser());
有效。
答案 1 :(得分:1)
泛型仅供编译器使用,以确保您不违反指定类型的规则。在运行时,所有泛型都转换为Object
,但确保类型安全,因为编译器会通知您任何违规或类型安全。为了达到这个目的,你需要告诉编译器你正在尝试使用什么,这就是为什么不推断泛型。
使用java generics https://docs.oracle.com/javase/tutorial/java/generics/genMethods.html
检查擦除