【问题标题】:Java Lambda expression Parameter data typeJava Lambda 表达式 参数数据类型
【发布时间】:2018-07-21 17:39:31
【问题描述】:
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);

【问题讨论】:

  • 你试过这些例子吗?这些不适用于List&lt;String&gt;

标签: java string list lambda foreach


【解决方案1】:

如果我理解正确,我认为这是一个更笼统的问题。 当您声明List&lt;String&gt; namesList 时,意味着您只能在namesList 中添加字符串及其子类型。如果尝试添加其他内容,编译会抱怨,因为它从 namesList 的声明中知道它可以在 String 类型值上具有。

【讨论】:

    【解决方案2】:

    这种情况只有在创建通用对象类型列表时才有可能:

    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) 方法将被调用,所以根据文档:

    打印一个对象,然后终止该行。这个方法首先调用 String.valueOf(x) 来获取打印对象的字符串值,然后表现得好像它调用了 print(String) 和 println()。

    一般来说,Java 从来没有像动态语言那样真正的类型推断。

    【讨论】:

      【解决方案3】:

      在这个例子中,names的类型是如何推断出来的

      幕后发生的事情是 javac 从其 context 中推断变量 names 的类型,即从 Consumer 的签名中推断为 @987654324 @ 在您的具体示例中使用 Consumer&lt;String&gt;

      那么,您可能会问 javac 是如何做到这一点的?无需过多介绍 javac 查找与您的 lambda 表达式接近的信息并使用此信息来确定正确的类型应该是什么。

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

      如果我们添加具有不同数据类型的项目会发生什么。

      你会得到一个编译错误。这是泛型在编译时提供了更强大的类型检查的好处之一。

      javac 将强类型检查应用于泛型代码并在代码违反类型安全时发出错误。这样做的好处是修复编译时错误比修复运行时错误要容易得多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多