英文:
Why java cannot reconcile the `?` generic type from different sources
问题
我有一个(据我理解)针对特定领域的单子(Monad),它充当了Either/Try的组合和用于REST终端点调用的操作。这是一个带有单一类型泛型参数的类,用于其包含的值。因为某些函数仅用于副作用而不关心返回值,我通常将它们的返回值简单地注释为MyMonadThing<?>
。然而,这种模式在尝试在某些地方分叉逻辑时会引发问题。我不会展示单子类,但是这里有一个使用列表的示例,说明了问题:
public static void main(String[] args) {
map(Arrays.asList(1, 2, 3), t -> {
return t == 2? foo() : bar();
});
}
static <T, NewT> List<NewT> map(List<T> lst, Function<T, List<NewT>> fn) {
return lst.stream().flatMap(t -> fn.apply(t).stream()).collect(Collectors.toList());
}
static List<?> foo() {
return Arrays.asList("foo");
}
static List<?> bar() {
return Arrays.asList("bar");
}
这不会编译,因为三元运算符。出现以下错误:
- 类型不匹配:无法从List<capture#2-of ?>转换为List
我可以通过强制转换来修复这个问题(即return (List<?>) (t == 2? foo() : bar());
),但这只是奇怪的。假设Java允许这样运行,那么main中的结果将简单地是List<?>
类型,那么在什么情况下,由于不稳定的类型系统,这可能导致实际错误呢?
英文:
I have a (as I understand) monad in place made for specific domain, which acts as a combination of Either/Try and an action for rest endpoint call. It's a class with a single type generic parameter for it's contained value. Because some functions are only written for side effect and don't care for return value, I commonly annotated their return simply as MyMonadThing<?>
. However, such pattern gives me issue when trying to fork logic at some places. I won't show the monad class, but here is example using lists that illustrates the problem
public static void main(String[] args) {
map(Arrays.asList(1, 2, 3), t -> {
return t == 2? foo() : bar();
});
}
static <T, NewT> List<NewT> map(List<T> lst, Function<T, List<NewT>> fn) {
return lst.stream().flatMap(t -> fn.apply(t).stream()).collect(Collectors.toList());
}
static List<?> foo() {
return Arrays.asList("foo");
}
static List<?> bar() {
return Arrays.asList("bar");
}
This won't compile because of ternary.
- Type mismatch: cannot convert from List<capture#2-of ?> to
List<Object>
I can fix this by casting (ie return (List<?>) (t == 2? foo() : bar());
) but that's just odd. Suppose java did allow this to run, and the result in main would be simply of type List<?>
-- under what circumstances could this result in an actual error due to unsound type system?
专注分享java语言的经验与见解,让所有开发者获益!
评论