当前位置: 代码迷 >> java >> lambda 表达式和关联对象
  详细解决方案

lambda 表达式和关联对象

热度:112   发布时间:2023-07-25 18:59:56.0

假设我有一个来自 java 的 Predicate 接口:

        public interface Predicate<T> {

         boolean test(T t);
         default Predicate<T> negate() {
             return (t) -> !test(t);
         }
        }

现在,使用 lambda 表达式创建了 Predicate1 和 Predicate2 两个实现,它们将创建 1 个对象(假设是 oracle jvm)对应于每个表达式,例如

  Predicate1 = (t) -> {return false}.
  Predicate2 = (t) -> {return false}.

negate()函数对应创建多少个对象? 每个实现是一个对象吗? 即在这种情况下是两个(2),因为我们有 Predicate1 和 Predicate2 或者它只是一个?

实际上,源代码中的lambda表达式实际上并未直接编译为对象。 它实际上是对运行时构造lambda的指令。 JVM在lambda方面有很多自由。 因此,在这种情况下,谈论对象可能不适用。

创建的对象的实际数量在很大程度上取决于lambda的主体和JVM的实现。

提到以下内容:

  • 不必在每次评估中分配一个新对象。
  • 由不同的lambda表达式产生的对象不必属于不同的类(例如,如果主体相同)。
  • 评估产生的每个对象不必属于同一类(例如,可以内联捕获的局部变量)。
  • 如果“现有实例”可用,则不必在先前的lambda评估中创建它(例如,可能在封闭类的初始化期间分配了它)。

看到:

  • 有关lambdas的Stackoverflow帖子
  • 对同一帖子
  • 到另一个问题

您可以使用以下程序进行检查,我们看到所有对象都是不同的,并且“ negate”返回的对象的类已被重用。 输出为:

domain.UseLambda$$Lambda$1/834600351@3e3abc88
domain.UseLambda$$Lambda$2/1418481495@6ce253f1
domain.Predicate$$Lambda$3/135721597@53d8d10a
domain.Predicate$$Lambda$3/135721597@e9e54c2
domain.Predicate$$Lambda$3/135721597@65ab7765
class domain.UseLambda$$Lambda$1/834600351
class domain.UseLambda$$Lambda$2/1418481495
class domain.Predicate$$Lambda$3/135721597
class domain.Predicate$$Lambda$3/135721597
class domain.Predicate$$Lambda$3/135721597

测试码

package uselambda;

class UseLambda {

  public static void main(String[] args) {
    Predicate<String> p1 = (t) -> {
      return false;
    };
    Predicate<String> p2 = (t) -> {
      return false;
    };

    Predicate<String> p3 = p1.negate();
    Predicate<String> p4 = p2.negate();
    Predicate<String> p5 = p2.negate();
    System.out.println(p1);
    System.out.println(p2);
    System.out.println(p3);
    System.out.println(p4);
    System.out.println(p5);

    System.out.println(p1.getClass());
    System.out.println(p2.getClass());
    System.out.println(p3.getClass());
    System.out.println(p4.getClass());
    System.out.println(p5.getClass());
  }
}

interface Predicate<T> {
  boolean test(T t);

  default Predicate<T> negate() {
      return (t) -> !test(t);
  }
}
  相关解决方案