具有lambda表达式

时间:2016-12-05 10:34:15

标签: java generics

我目前正在通过Java核心书籍和我在通用章节中的工作方式。我在这里无法掌握一件事。正如书中所述,你不能在泛型类中用T创建一个新对象,所以这是不可能的

public foo() { first = new T(); second = new T(); } //ERROR

你可以做的是使用功能接口和lambda表达式,参考像这样的构造函数

foo<String> f = foo.makeFoo(String::new)
public static <T> foo<T> makeFoo(Supplier<T> constr)
{
    return new foo<>(constr.get(), constr.get());
}

它很棒,按预期工作,但只有String,如果我想使用任何其他对象,例如包裹简单类型整数,它是不可能的。它给了我这个错误

Error:(35, 38) java: method makeFoo in class generic.foo<T> cannot be applied to given types;
required: java.util.function.Supplier<T>
found: Integer::new
reason: cannot infer type-variable(s) T
(argument mismatch; incompatible parameter types in method reference)

似乎只使用String,我不知道为什么,我认为它适用于每个对象

我试图在正确的类上创建所有这些对象

  foo<String> fString = foo.makeFoo(String::new); //Works
  foo<Integer> fInteger = foo.makeFoo(Integer::new); //Doesn't work
  foo<Double> fDouble = foo.makeFoo(Double::new); //Doesn't work

修改

实际上这适用于自定义对象,只包含简单类型,不会编译

foo<MyCustomObject> fCustom = foo.makeFoo(MyCustomObject::new); //Works

1 个答案:

答案 0 :(得分:1)

由于lexicore指出我们不能使表达式Integer :: new,因为没有Integer对象的no-arg构造函数。使用整数的正确语法可以像这样简单,其中arg是int变量

foo<Integer> f = foo.makeFoo(() -> (arg));

这里不需要包装新的整数(arg)。

有关该主题的更多信息:Java 8 Supplier with arguments in the constructor