2

我已经切换到 Java 7 build 21 并开始出现奇怪的编译错误。例如,下面的代码片段无法编译(尽管 IntelliJ 没有显示任何错误):

    1 Iterable<?> parts = ImmutableList.<String>of("one", "two");
    2 Function<?, String> function = new Function<Object, String>() {
    3    @Override
    4    public String apply(final Object input) {
    5        return input.toString();
    6    }
    7 };
    8 Iterable<String> result = Iterables.transform(parts, function);
    9 System.out.println(result);

但如果我在第 2 行替换?Object

    2 Function<Object, String> function = new Function<Object, String>() {

然后编译成功。

我得到的错误有点神秘:

error: method transform in class Iterables cannot be applied to given types;
required: Iterable<F>,Function<? super F,? extends T> 
found: Iterable<CAP#1>,Function<CAP#2,String> 
reason: no instance(s) of type variable(s) F,T exist so that argument type Function<CAP#2,String>
conforms to formal parameter type Function<? super F,? extends T> 
where F,T are type-variables:
F extends Object declared in method <F,T>transform(Iterable<F>,Function<? super F,? extends T>) 
T extends Object declared in method <F,T>transform(Iterable<F>,Function<? super F,? extends T>) 
where CAP#1,CAP#2 are fresh type-variables: 
CAP#1 extends Object from capture of ?
CAP#2 extends Object from capture of ? extends Object

将第 2 行更改为

    2 Function<? extends Object, String> function = new Function<Object, String>() {

没有效果。

我正在使用 JDK 1.7.0_11-b21;这曾经用 build 4 编译好。

这是一个javac错误还是我的?

4

3 回答 3

6

方法签名是:

<F,T> Iterable<T> transform(Iterable<F> fromIterable, Function<? super F,? extends T> function) 

这对于类型参数 F 意味着什么:

Iterable<F> :
    F can be any type here, but will influence the type parameter to Function
Function<? super F, ? extends T> :
    the first type parameter (? super F) MUST be a supertype of F

当您键入:

Iterable<?>
Function<?, String>

你说的是任何东西的 Iterable ,所以它可能是 eg Iterable<Integer>。您还说从任何东西到字符串的函数,所以它可能是Function<String, String>. 由于 String 不是 Integer 的超类,因此您不满足(? super F)条件。

于 2013-01-21T15:31:28.303 回答
2

这是因为Function<?,String>可以是Function<Object,String>, Function<String,String>,中的任何一个Function<Foo,String>。因此,您无法将 Object 输入到 Function 中是正确的,因为它实际上可能需要 Foo 代替。

当然,既然你Iterable<?>,只知道Iterable吐出Objects,那你就只能用aFunction<Object,WhatEver>来改造了。

于 2013-01-21T15:15:50.000 回答
1

我实际上能够通过改变来解决这个问题

2 Function<?, String> function = new Function<Object, String>() {

2 Function<? super Object, String> function = new Function<Object, String>() {

当您考虑它时,这是有道理的 - 功能是这里的消费者(来自臭名昭着的PECS成语)。

于 2013-01-21T15:39:53.940 回答