Java何时需要显式类型参数?

吉利:

鉴于:

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

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

    public static final class MapCollectorBuilder<T, K, V>
    {
        public Collector<T, ?, ImmutableMap<K, V>> build()
        {
            return null;
        }
    }

    public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap2(
        Function<? super T, ? extends K> keyMapper,
        Function<? super T, ? extends V> valueMapper)
    {
        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.toImmutableMap(keyMapper, valueMapper).build());

        ImmutableMap<String, Integer> map2 = Stream.of("1", "2", "3")
            .collect(Testcase.toImmutableMap(i -> i, Integer::valueOf).build());

        ImmutableMap<String, Integer> map3 = Stream.of("1", "2", "3")
            .collect(Testcase.toImmutableMap2(i -> i, Integer::valueOf));
    }
}

该语句涉及map1map3编译良好,但map2失败:

Testcase.java:[41,57] incompatible types: cannot infer type-variable(s) T,K,V
    (argument mismatch; invalid method reference
      no suitable method found for valueOf(java.lang.Object)
          method java.lang.Integer.valueOf(java.lang.String) is not applicable
            (argument mismatch; java.lang.Object cannot be converted to java.lang.String)
          method java.lang.Integer.valueOf(int) is not applicable
            (argument mismatch; java.lang.Object cannot be converted to int))

可以通过提供显式类型参数来解决编译器错误<String, String, Integer>

  1. Java 8何时需要显式类型参数?意思是,是否有一个已知的打破类型推断的模式?
  2. 可以toImmutableMap()MapCollectorBuilder进行更改以避免显式类型参数,而又不会失去使用Builder来配置收集器的功能吗?

更新

  1. 为什么涉及map3工作的陈述它与涉及的声明map2有何不同
霍尔格:

要回答您的问题“意思是,有一个已知的模式会破坏类型推断吗?” 简短地说:当然,有一种模式,而且对于Java编程语言的整个行为都有一个巨大的规范

但是有关类型推断和方法调用类型的章节确实详尽且难以理解。这可以通过以下事实得到最好的说明:在发生意外行为的情况下,通常会根据规范对预期行为进行大量讨论。

但是对于程序员来说有些地方是可以解释和记住的。

有两种方法可以通过传递给组成表达式的方法或部分的参数或表达式的目标类型(即,调用参数的预期类型)来推断类型参数的方式如果有return语句,则分配该值或方法的返回类型。

目标类型可以通过嵌套方法调用传播,例如

TargetType x=foo(bar(/*target type can be used*/));

或有条件的

TargetType x=condition? foo(/*target type can be used*/): foo(/*target type can be used*/);

不是

TargetType x=foo(/*target type can NOT be used*/).foo();

现在来看您的示例:

ImmutableMap<String, Integer> map1 = Stream.of("1", "2", "3").collect( expression );

此处,Stream.of(…).collect(…)链接在一起的,因此不能使用目标类型来确定of调用的流类型,但是提供给该方法的参数足以推断出类型Stream<String>collect方法提供分配给结果的结果map1,因此,流类型Stream<String>目标类型ImmutableMap<String, Integer>都是已知的,并且可用于表达式的类型推断在表达式上:

  • Testcase.toImmutableMap(keyMapper, valueMapper).build()这是一个链式调用,因此目标类型是已知的,build()但不是toImmutableMap但是,to的参数toImmutableMap是具有已知精确类型的局部变量,因此类型推断可以使用它们来推断的结果类型,toImmutableMap并检查其是否符合预期。.build()

  • Testcase.toImmutableMap(i -> i, Integer::valueOf).build()这又是一个链式调用,但是现在参数i - > i具有不完整的类型,并且由于缺少目标类型而受到影响。i -> i不了解目标类型的情况下猜测类型的尝试失败。

  • Testcase.toImmutableMap2(i -> i, Integer::valueOf)不是链式调用,因此目标类型可用于该toImmutableMap2调用(就该collect调用而言,它是一个嵌套调用)。因此,的目标类型toImmutableMap2允许推断参数的目标类型,从而推断i -> ilambda表达式。使用正确的目标类型,可以推断出正确的功能签名。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

显式类型参数

来自分类Dev

为什么C ++和Java中的构造函数调用需要显式类型参数?

来自分类Dev

PowerShell 中的系统 DLL 何时需要显式添加类型调用?

来自分类Java

显式类型参数多余?

来自分类Dev

Java泛型-构造函数调用的显式类型参数

来自分类Dev

为什么在这里需要显式类型参数列表?

来自分类Dev

为什么我得到E2531“方法需要显式类型参数”

来自分类Java

您何时需要显式调用超类构造函数?

来自分类Dev

显式类型参数Kotlin和RxJava

来自分类Dev

基于参数的显式返回类型

来自分类Dev

何时在 C++ 中显式指定模板参数?

来自分类Dev

plpgsql:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换

来自分类Dev

PostgreSQL错误没有函数与给定的名称和参数类型匹配。您可能需要添加显式类型转换

来自分类Dev

没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换

来自分类Java

为什么我不能显式地将类型参数传递给泛型Java方法?

来自分类Dev

如何在不指定类的情况下使用显式类型参数调用Java方法?

来自分类Java

Java中的显式类型转换示例

来自分类Dev

为什么Polymer的计算属性需要显式属性参数?

来自分类Dev

为什么不需要显式设置通用参数?

来自分类Dev

您可能需要添加显式类型转换

来自分类Dev

在A a =(A)b中是否需要显式类型转换;

来自分类Dev

为什么对n级类型需要显式的forall量词?

来自分类Dev

显式类型参数“<>”如何在 Android 4.1 上工作?

来自分类Java

为什么显式类型参数应该用菱形替换?

来自分类Dev

如何返回我显式传递为参数的类型?

来自分类Java

使用显式类型参数调用静态导入的方法

来自分类Dev

显式转换模板非类型参数时出错

来自分类Dev

如何使用显式类型参数实例化通用记录?

来自分类Dev

通过显式类获取可变模板非类型参数

Related 相关文章

  1. 1

    显式类型参数

  2. 2

    为什么C ++和Java中的构造函数调用需要显式类型参数?

  3. 3

    PowerShell 中的系统 DLL 何时需要显式添加类型调用?

  4. 4

    显式类型参数多余?

  5. 5

    Java泛型-构造函数调用的显式类型参数

  6. 6

    为什么在这里需要显式类型参数列表?

  7. 7

    为什么我得到E2531“方法需要显式类型参数”

  8. 8

    您何时需要显式调用超类构造函数?

  9. 9

    显式类型参数Kotlin和RxJava

  10. 10

    基于参数的显式返回类型

  11. 11

    何时在 C++ 中显式指定模板参数?

  12. 12

    plpgsql:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换

  13. 13

    PostgreSQL错误没有函数与给定的名称和参数类型匹配。您可能需要添加显式类型转换

  14. 14

    没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换

  15. 15

    为什么我不能显式地将类型参数传递给泛型Java方法?

  16. 16

    如何在不指定类的情况下使用显式类型参数调用Java方法?

  17. 17

    Java中的显式类型转换示例

  18. 18

    为什么Polymer的计算属性需要显式属性参数?

  19. 19

    为什么不需要显式设置通用参数?

  20. 20

    您可能需要添加显式类型转换

  21. 21

    在A a =(A)b中是否需要显式类型转换;

  22. 22

    为什么对n级类型需要显式的forall量词?

  23. 23

    显式类型参数“<>”如何在 Android 4.1 上工作?

  24. 24

    为什么显式类型参数应该用菱形替换?

  25. 25

    如何返回我显式传递为参数的类型?

  26. 26

    使用显式类型参数调用静态导入的方法

  27. 27

    显式转换模板非类型参数时出错

  28. 28

    如何使用显式类型参数实例化通用记录?

  29. 29

    通过显式类获取可变模板非类型参数

热门标签

归档