【问题标题】:Java double colon operator reference (::)Java 双冒号运算符参考 (::)
【发布时间】:2017-03-30 09:48:27
【问题描述】:

test::testMethod == test::testMethod

真的吗?我想知道它们是否会引用同一个对象。此代码无法编译。但可能有几种情况需要澄清。

我怀疑这将扩展到

Runnable r = () -> test.testMethod()
Runnable r1 = () -> test.testMethod()

以及以下是否属实。

r == r1

【问题讨论】:

  • 如果代码不能编译,那么询问结果是否为true是没有意义的。请提供一个确实编译的完整示例。
  • 我怀疑答案是它没有指定 - JLS 15.13.3:“接下来,分配并初始化具有以下属性的类的新实例,或者类的现有实例引用了以下属性。” (我看不到有关重用实例的情况的详细信息。)
  • Does a lambda expression create an object on the heap every time it's executed?。简而言之,它是故意未指定的。可能是true,但不是必须的。而在当前的 JRE 中,情况并非如此。您还可以追溯this answer 的测试,该测试表明,在哪些情况下,当前实现中的对象是相同的。

标签: java java-8


【解决方案1】:

即使您的代码可以编译并且test::testMethod 声明为Runnable,答案test::testMethod == test::testMethod 始终返回false,因为您与两个差异类实例进行比较。对于每个 lambda 表达式,编译器将为它创建一个 synthentic 匿名内部类。例如:

//a synthentic anonymous lambda class A implemented Runnable
Runnable r = () -> test.testMethod(); 

//a synthentic anonymous lambda class B implemented Runnable
Runnable r1 = () -> test.testMethod();

r.getClass().equals(r1.getClass());// always return false

【讨论】:

    【解决方案2】:

    我们看下面的例子:

    Predicate<String> predicate = String::isEmpty;
    
    Function<String,Boolean> function = String::isEmpty;
    
    System.out.println(predicate.equals(function)); // false
    

    lambda 不包含有关其类型的任何信息。该信息是从上下文中推断出来的。同一个lambaString::inEmpty可以代表不同的功能接口,就像我们在上面看到的那样。

    【讨论】:

      猜你喜欢
      • 2013-11-28
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多