编译器抱怨"实际和正式的参数列表长度不同,但它们没有

时间:2015-07-12 15:55:50

标签: java generics

编译以下代码时:

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;

public class Testcase
{
    public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap1(
        Function<? super T, ? extends K> keyMapper,
        Function<? super T, ? extends V> valueMapper)
    {
        return null;
    }

    public static <T, K, V> MapCollectorBuilder<T, K, V, ? extends Map<K, V>, ImmutableMap<K, V>>
        toImmutableMap2(Function<? super T, ? extends K> keyMapper,
            Function<? super T, ? extends V> valueMapper)
    {
        return null;
    }

    public final class MapCollectorBuilder<T, K, V, A extends Map<K, V>, R extends Map<K, V>>
    {
        /**
         * @return a new collector
         */
        public Collector<T, A, R> build()
        {
            return null;
        }
    }

    public void main(String[] args)
    {
        Function<String, String> keyMapper = i -> i;
        Function<String, Integer> valueMapper = Integer::valueOf;

        ImmutableMap<String, Integer> map1 = Stream.of("1", "2", "3")
            .collect(Testcase.toImmutableMap1(keyMapper, valueMapper));

        MapCollectorBuilder<String, String, Integer, Map<String, Integer>, ImmutableMap<String, Integer>> builder
            = Testcase.
            <String, String, Integer, Map<String, Integer>, ImmutableMap<String, Integer>>toImmutableMap2(
                keyMapper, valueMapper);

        ImmutableMap<String, Integer> map2 = Stream.of("1", "2", "3").collect(builder.build());
    }
}

我收到以下错误:

Testcase.java:[45,35] method toImmutableMap2 in class Testcase cannot be applied to given types;
  required: java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends V>
  found: java.util.function.Function<java.lang.String,java.lang.String>,java.util.function.Function<java.lang.String,java.lang.Integer>
  reason: actual and formal argument lists differ in length

但据我所知,参数列表是正确的。

  1. 为什么toImmutableMap1()编译时toImmutableMap2()没有?
  2. 如何正确编译{{1}?
  3. UPDATE :如果我用toImmutableMap2()替换5个类型的参数,我会遇到这个新的编译器错误:

    <String, String, Integer>

1 个答案:

答案 0 :(得分:2)

目前您正在尝试在此处指定5个类型参数:

Testcase.
    <String, String, Integer, Map<String, Integer>, ImmutableMap<String, Integer>>toImmutableMap2(

...但该方法只有3个类型参数:

public static <T, K, V> ComplexReturnTypeHere<...> toImmutableMap2

您可以通过将呼叫更改为:

来解决此问题
Testcase.<String, String, Integer>toImmutableMap2(...)

但是这会将错误消息更改为:

Testcase.java:44: error: incompatible types: 
Testcase.MapCollectorBuilder<String,String,Integer,CAP#1,ImmutableMap<String,Integer>>
cannot be converted to 
Testcase.MapCollectorBuilder<String,String,Integer,Map<String,Integer>,
    ImmutableMap<String,Integer>>

可以通过更改方法声明的返回类型来修复:

public static <T, K, V>
    MapCollectorBuilder<T, K, V, Map<K, V>, ImmutableMap<K, V>>
    toImmutableMap2(
        Function<? super T, ? extends K> keyMapper,
        Function<? super T, ? extends V> valueMapper)

此处的区别在于MapCollectorBuilder - Map<K, V>而非? extends Map<K, V>中的第二种类型参数。

或者,您可以将builder的声明更改为:

MapCollectorBuilder<String, String, Integer, ? extends Map<String, Integer>, ImmutableMap<String, Integer>> builder

(请注意,就此而言,感觉它正在落入“令人难以置信的阅读和理解”代码的范围......)