0

Say I have a Predicate interface from java :

        public interface Predicate<T> {

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

Now, two implementation are created Predicate1 and Predicate2 using lambda expressions and they will have 1 object created(assuming oracle jvm) corresponding to each expression like

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

How many objects will be created corresponding to negate() function? Will it be one object per implementation. ie two(2) in this case as we have Predicate1 and Predicate2 or will it be just one ?

user2599052
  • 1,056
  • 3
  • 12
  • 27
  • 2
    There will be two implementations of `negate()`: one for each predicate. I wouldn't call them objects though. – Maurice Perry Feb 25 '19 at 08:03
  • So far this is noop code, which should result in that: nothing. What real objects are created then depends how you acces the objects and what assumptions the jvm can make. But the given code as is shouldn't create any object as it is obviously never used. – kai Feb 25 '19 at 08:42
  • @Its assumed that operation will be called on Predicate1 and Predicate2 including the negate() – user2599052 Feb 25 '19 at 08:45
  • like I said: the jvm will try to inline and use precalculated values as possible. In obvious cases it will succeed in more complex cases it won't. – kai Feb 25 '19 at 08:47
  • see for example escape analysis in https://docs.oracle.com/en/java/javase/11/vm/java-hotspot-virtual-machine-performance-enhancements.html (unfortunatly this a complex topic and it is difficult to find something compact, that covers all but it may give you a first impression of what the jvm tries) – kai Feb 25 '19 at 09:06
  • Well, a lambda expression in the source code is not actually directly compiled to an object; it is rather an instruction to the runtime to construct a lambda. The JVM has a lot of freedom regarding lambdas; so it might be that speaking of objects is not applicable in this context. – MC Emperor Feb 25 '19 at 09:21
  • @MCEmperor exactly. I just was unable to find anything compact that covers it realy: its allways peaces and blog posts of developers that explain some particular optimization. The link was the best i could come up with .... – kai Feb 25 '19 at 09:29

1 Answers1

0

A lambda expression in the source code is not actually directly compiled to an object; it is rather an instruction to the runtime to construct a lambda. The JVM has a lot of freedom regarding lambdas; so it might be that speaking of objects is not applicable in this context.

The actual number of objects being created heavily depends on the body of the lambda and the implementation of the JVM.

The JLS § 15.27.4 mentions the following:

  • A new object need not be allocated on every evaluation.
  • Objects produced by different lambda expressions need not belong to different classes (if the bodies are identical, for example).
  • Every object produced by evaluation need not belong to the same class (captured local variables might be inlined, for example).
  • If an "existing instance" is available, it need not have been created at a previous lambda evaluation (it might have been allocated during the enclosing class's initialization, for example).

See:

MC Emperor
  • 22,334
  • 15
  • 80
  • 130