【问题标题】:Java generic object with lambda expressions带有 lambda 表达式的 Java 泛型对象
【发布时间】:2016-12-05 10:34:14
【问题描述】:

我目前正在阅读 Java Core 书籍,并且正在阅读通用章节。我在这里无法掌握一件事。正如书上所说,你不能在泛型类中用 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,如果我想与任何其他对象一起使用,例如包装简单类型 Integer,这是不可能的。它给了我这个错误

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)

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

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

  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

【问题讨论】:

  • 变量f的类型是foo&lt;String&gt;,所以显然它期望供应商返回一个String对象。如果您为其提供返回 Integer 对象的供应商,请将其更改为 foo&lt;Integer&gt;
  • 我正在这样做,这给出了无法应用的错误。 foo fInteger = foo.makeFoo(Integer::new);
  • @MTomczyński 我拒绝了你对我的答案的编辑,因为我没有写太多的文本/代码。我认为如果您将其发布为您自己的问题的答案会更好,这是绝对合适的。

标签: java generics


【解决方案1】:

String 相比,Integer 没有无参数构造函数。所以Integer::new 不是Supplier&lt;Integer&gt;makeFoo(Object::new) 会起作用。

【讨论】:

    【解决方案2】:

    正如 lexicore 指出的那样,我们无法创建表达式 Integer::new,因为没有 Integer 对象的无参数构造函数。正确的整数语法可以像这样简单,其中 arg 是 int 变量

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

    这里不需要用 new Integer(arg) 换行。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-25
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      相关资源
      最近更新 更多