java - 通用功能接口(interface)和类型删除

标签 java generics lambda java-8

下面的编译错误是什么意思?

FooSetter 类型中的 apply(Sample.Foo, capture#5-of ?) 方法不适用于参数 (Sample.Foo, 捕获#6-of ?)

它出现在下面的代码中(在我用注释指出的底部),它尝试将一个 bean 的 setter 映射到另一个 bean 的 getter 而不进行强制转换(是的,我知道有实用程序可以做到这一点,但是这个是一个例子)。我使用的是以下两个功能接口(interface)

@FunctionalInterface
public interface FooSetter<V> {
    void apply(Foo foo, V value);
} 


@FunctionalInterface
public interface BarGetter<T> {
   T apply(Bar from); 
}


public class Sample {

public static class Bar{
    public String description;
    public Integer num;

    public String getDecription(){
        return description;
    }
    public void setDescription(String desc){
        this.description = desc;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
}

public static class Foo{

    private String name;
    private Integer age;

    public Foo setName(String name){
        this.name = name;
        return this;
    }

    public Foo setAge(int age){
        this.age = age;
        return this;
    }

    @Override
    public String toString(){
        return "Name" + name + "  Age " + age;
    }
}

public static void main(String[] args) throws Exception  {

    HashMap<String, BarGetter<?>> barGetters= Maps.newHashMap();
    barGetters.put("description", (BarGetter<String>)(Bar b) -> b.getDecription());
    barGetters.put("num", (BarGetter<Integer>)(Bar b) -> b.getNum());

    HashMap<String, FooSetter<?>> fooSetters= Maps.newHashMap();
    fooSetters.put("name",   (Foo f, String name) -> f.setName(name));
    fooSetters.put("age",   (Foo f, Integer age) -> f.setAge(age));

    HashMap<String,String> fooFromBar = Maps.newHashMap();
                 // FOO      BAR
    fooFromBar.put("name", "description");
    fooFromBar.put("age", "num");

    Bar bar  = new Bar();
    bar.setDescription("bar desc");
    bar.setNum(5);

    Foo newFoo = new Foo();
    for (String key : fooFromBar.keySet()) {
       //COMPILATION ERROR  
       fooSetters.get(key).apply(newFoo, barGetters.get( fooFromBar.get(key) ).apply(bar) );
    }
 }
}

关于类型删除,我在这里没有看到什么吗?

最佳答案

这个

fooSetters.get(key)

返回 FooSetter<?> 类型的值, IE。一个FooSetter它不知道它设置的类型。它的apply因此方法具有以下(推断的)定义

void apply(Foo foo, ? value);

除了 null 之外,您不能将此方法与任何其他参数一起使用(作为其第二个参数) (可用于任何引用类型),因为您不知道它是什么类型。

这个

barGetters.get( fooFromBar.get(key) )

返回 BarGetter<?> 类型的值,即 BarGetter它不知道它会得到什么。它的apply因此方法显示为

? apply(Bar from);

这个?可能与fooSetter.apply完全不同。正在期待。

因此,类型系统不允许这样做,并会给出编译错误。

关于java - 通用功能接口(interface)和类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28032182/

相关文章:

java - 如何使用自定义类作为迭代器的类型变量?

c# - 如何发出 System.Linq.Expression?

c# - 来自 lambda 的带有构造函数参数的 RelayCommand

java - Android 模拟器无法启动应用程序

java - 如何删除行并编辑 JTable 上保存的任何数据并将其更新到 mySQL 数据库

java - 实行预约系统

vb.net - 与 VB .net Lambdas 斗争

java - 使用 Selenium Grid 时的 ChromeDriver 日志记录

C# 泛型类作为参数,T 与泛型类的调用方法相同

java - 返回泛型类类型