java - map <字符串,? super Number> 用于添加和 Map<String, ?用于打印的扩展 Number> 会产生错误

标签 java generics

我已经阅读了这里有关此主题的几篇文章。

This是一篇特别好的帖子

我以为我理解了PECS概念,并尝试设置一个小例子来测试它。

import java.util.Map;
import java.util.HashMap;

class Test {
    public static void main(String[] args) {
        Map<String, ? super Number> map = new HashMap<>();
        map.put("int", 1);
        map.put("double", 1.0);
        map.put("long", 100000000000L);

        print(map);

    }

    public static void print(Map<String, ? extends Number> map) {
        map.forEach((k, v) -> System.out.printf("Key: %s, Val: %s%n", k, v));
    }
}

我知道我需要使用 super 才能将多个子类型插入到同一个 map 中。

但是说到打印。我认为使用 extends 就足够了,因为 PECS(生产者扩展)

相反,我得到了这个:

Error:(12, 15) java: incompatible types: java.util.Map<java.lang.String,capture#1 of ? super java.lang.Number> cannot be converted to java.util.Map<java.lang.String,? extends java.lang.Number>

最佳答案

在这两种情况下Number就足够了,而且是最充分的。

如前所述super没有意义;您也可以编写 Object。

Map<String, Number> map = new HashMap<>();

使用此功能,您可以将 Number 或 Number 的子级放入 map 中。 或者从 map 中获取 Number 或 Number 的父级。

现在如果你想使用:

public static void print(Map<String, ? extends Number> map) {

你不能输入 Double (或其他)进入map因为实际的 map 参数可能是 Map<String, Integer> 。因此Map<String, Number> .

由于java的类型系统不是很强/表达力很强,一个好的规则是保留extends用于元级别构造(=当您需要它们时)。对于简单的数据结构,PECS 遵循数据流。

关于java - map <字符串,? super Number> 用于添加和 Map<String, ?用于打印的扩展 Number> 会产生错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44175613/

相关文章:

java - java.util.Arrays.copyOf(U[], int, Class<? extends T[]>) 中通用通配符的优点

java - 对于泛型和原始类型都是可迭代的

Java 泛型 - 冗余类型初始化

Python3 typehints - 传入类型的元组后,指定返回值是这些类型的实例的元组

c# - 尝试将 LOX 语言实现从 Crafting Interpreter 的书中移植到 C# 时遇到泛型问题

java - 使用各种重写方法调用对象方法

java - 在 Java 中将本地时间转换为 UTC

java - Java中1.5亿位数字的平方

java - Hibernate 源代码中的 volatile 屏障将为 "syncs state with other threads"。如何?

java - 不使用 Random 类生成唯一的 4 位随机数