лямбда-выражение и связанный объект - PullRequest
0 голосов
/ 25 февраля 2019

Скажем, у меня есть интерфейс Predicate из java:

        public interface Predicate<T> {

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

Теперь две реализации созданы Predicate1 и Predicate2 с использованием лямбда-выражений, и у них будет создан 1 объект (при условии, что oracle jvm) соответствует каждому выражению, например

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

Сколько объектов будет создано в соответствии с функцией negate()?Будет ли это один объект на реализацию.т.е. два (2) в этом случае, поскольку у нас есть Предикат1 и Предикат2 или это будет только один?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Вы можете использовать следующую программу, чтобы проверить это, мы видим, что все объекты различны, и класс объектов, возвращаемых "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);
  }
}
0 голосов
/ 25 февраля 2019

Лямбда-выражение в исходном коде фактически не скомпилировано напрямую с объектом;это скорее инструкция к среде выполнения для создания лямбды.У JVM есть много свободы относительно лямбд;возможно, речь об объектах неприменима в этом контексте.

Фактическое количество создаваемых объектов сильно зависит от тела лямбды и реализации JVM.

JLS § 15.27.4 упоминает следующее:

  • Новый объект не требуется выделять при каждой оценке.
  • Объекты, созданные различными лямбда-выражениямине должны принадлежать к разным классам (например, если тела идентичны).
  • Каждый объект, созданный в результате оценки, не обязательно должен принадлежать одному и тому же классу (например, захваченные локальные переменные могут быть встроенными).
  • Если «существующий экземпляр» доступен, его не нужно было создавать при предыдущей лямбда-оценке (например, он мог быть выделен во время инициализации окружающего класса).

См .:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...