Java Lambda表达式参数数据类型

时间:2018-07-21 17:39:31

标签: java string list lambda foreach

public class Example{
  public static void main(String[] args){
  List<String> list=new ArrayList<String>();
   list.add("Rick");
   list.add("Negan");
    list.add("carl");

    list.forEach(
      (names)->System.out.println(names)
    );
  }
}

在此示例中,如何推断names的类型。 如果我们添加具有不同数据类型的项目,将会发生什么。 例如:

list.add(new Person());
list.add(new Integer(3);

3 个答案:

答案 0 :(得分:1)

如果我理解正确的话,我认为这更多是通用问题。 当您声明List<String> namesList时,您只能在namesList中添加字符串及其子类型。如果尝试添加其他内容,则编译会抱怨,从namesList的声明中得知,它可以具有String类型的值。

答案 1 :(得分:0)

仅当您创建通用对象类型的列表时,这种情况才可能发生:

public class Example {
    public static void main(String[] args){
        List<Object> list= new ArrayList<>();

        list.add("Rick");
        list.add(new Person());
        list.add(new Integer(3);

        list.forEach(name->System.out.println(name));
    }
}

System.out.println(Object)方法将被调用,因此根据doc:

  

打印一个对象,然后终止该行。此方法首先调用String.valueOf(x)来获取打印对象的字符串值,然后像先调用print(String)然后调用println()一样操作。

通常,Java从来没有像动态语言这样的真类型推断。

答案 2 :(得分:0)

  

在此示例中,如何推断names的类型

幕后发生的事情是 javac 从其上下文即{{1}的签名中推断出变量names的类型。 }(在您的特定示例中为Consumer)消耗了forEach

因此,您可能会问 javac 是如何做到的? javac 会在不太多细节的情况下查找与您的lambda表达式接近的信息,并使用此信息来确定正确的类型。

也就是说, javac 不能总是推断类型,在这种情况下,您需要提供类型提示。

  

如果我们添加其他数据类型的项目,会发生什么情况。

您将收到编译错误。这是泛型在编译时提供更强类型检查的好处之一。

Consumer<String>将强类型检查应用于通用代码,如果代码违反类型安全,则会发出错误。这样做的好处是,修复编译时错误比修复运行时错误容易得多。