【问题标题】:Java Generics bounded wildcardsJava 泛型有界通配符
【发布时间】:2020-06-13 18:55:21
【问题描述】:

这是我用来学习 Java 流的一个相当人为的示例,但我相信我遇到了一个通用的通配符问题。我的代码如下。我正在尝试从列表中读取每个 Employee 对象,应用一个函数来获取 id 并将其重新设置在一个新的员工对象中。但是,代码不会在 key.apply(emp) 方法中正确编译。错误消息对调试不是特别有用,因为它只是说,必需类型:捕获?扩展提供的数字:捕获?扩展数字。所需的和提供的看起来是一样的。我错过了什么?

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;

public class Employee {
    private int id;
    private String name;
    Map<Function<Employee,? extends Number>, BiConsumer<Employee, ? extends Number>> map = new HashMap<>();

    public Employee(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public Employee() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Function<Employee, Integer> func = Employee::getId;

    public BiConsumer<Employee, Integer> c = Employee::setId;

    public static void main(String[] args) {
        Employee e = new Employee();
        e.m1();
    }

    private void m1() {
        List<Employee> l = new ArrayList<>();
        l.add(new Employee("A", 100));
        l.add(new Employee("B", 100));
        l.add(new Employee("A", 101));
        l.add(new Employee("D", 102));
        l.add(new Employee("E", 103));
        l.add(new Employee("F", 104));
        l.add(new Employee("F", 102));
        Employee e = new Employee();
        map.put(func, c);
        map.forEach((key, value) -> l.stream()
                .forEach(emp -> value.accept(e, key.apply(emp)))); 
// key.apply(emp) shows a squigly line as an error.
//The error is,
//Required type: capture of ? extends Number 
//Provided: capture of ? extends Number. 
    }
}

【问题讨论】:

    标签: java generics bounded-wildcard


    【解决方案1】:

    那个问题是: get-put-principle

    Get 和 Put 原则:仅在获取时使用扩展通配符 结构中的值,当你只放值时使用超级通配符 放入结构中,并且在 get 和 put 时都不要使用通配符。

    据此:

    List<? super Number> list1 = new ArrayList<>();
    list1.add(new Integer(1));  // works
    list1.add(new Double(2.2)); // works
    
    List<Number> list2 = new ArrayList<>();
    list2.add(new Integer(1));  // works
    list2.add(new Double(2.2)); // works
    
    List<? extends Number> list3 = new ArrayList<>();
    list3.add(new Integer(1));  // doesn't work
    list3.add(new Double(2.2)); // doesn't work
    

    【讨论】:

    • 相关:PECS(生产者扩展,消费者超级)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多