F
F
floppa3222020-10-18 23:25:46
Java
floppa322, 2020-10-18 23:25:46

Closure Vs Common Function pointer?

Is there a difference between obj.func(this::someMethod) vs obs.func(lambda / anonymous class) from memory?
Indeed, in the case of a reference to a method, you cannot access variables outside the method (closure), and in the case of a lamb / anonymous class, you can

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Gornostaev, 2020-10-19
@Lite_stream

If a lambda or an anonymous class does not use variables from the enclosing scope, then the compiler will not capture them and there will be no difference with a method reference. To verify this, let's do an experiment. We need three classes:

import java.util.function.Supplier;

public class ExampleWithMethodRef {
    private static String someMethod() {
        return "Internal value";
    }

    public static void main(String[] args) {
        String value = "External value";
        Supplier<String> lambda = ExampleWithMethodRef::someMethod;
    }
}

import java.util.function.Supplier;

public class ExampleWithLambda {
    public static void main(String[] args) {
        String value = "External value";
        Supplier<String> lambda = () -> "Internal value";
    }
}

import java.util.function.Supplier;

public class ExampleWithCapturingLambda {
    public static void main(String[] args) {
        String value = "External value";
        Supplier<String> lambda = () -> value;
    }
}

Let's compile all three and run with a parameter -Djdk.internal.lambda.dumpProxyClasses=.Classes will appear in the working directory into which lambdas and method references expand. Let's see what they have inside:
javap -p -c ExampleWithMethodRef$$Lambda$1
final class ExampleWithMethodRef$$Lambda$1 implements java.util.function.Supplier {                       
  private ExampleWithMethodRef$$Lambda$1();                                                               
    Code:                                                                                                 
       0: aload_0                                                                                         
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V                       
       4: return                                                                                          
                                                                                                          
  public java.lang.Object get();                                                                          
    Code:                                                                                                 
       0: invokestatic  #19                 // Method ExampleWithMethodRef.someMethod:()Ljava/lang/String;
       3: areturn                                                                                         
}

javap -p -c ExampleWithLambda$$Lambda$1
final class ExampleWithLambda$$Lambda$1 implements java.util.function.Supplier {                          
  private ExampleWithLambda$$Lambda$1();                                                                  
    Code:                                                                                                 
       0: aload_0                                                                                         
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V                       
       4: return                                                                                          
                                                                                                          
  public java.lang.Object get();                                                                          
    Code:                                                                                                 
       0: invokestatic  #19                 // Method ExampleWithLambda.lambda$main$0:()Ljava/lang/String;
       3: areturn                                                                                         
}

javap -p -c ExampleWithCapturingLambda$$Lambda$1
final class ExampleWithCapturingLambda$$Lambda$1 implements java.util.function.Supplier {                                            
  private final java.lang.String arg$1;
                                                                                                                                     
  private ExampleWithCapturingLambda$$Lambda$1(java.lang.String);                                                                    
    Code:                                                                                                                            
       0: aload_0                                                                                                                    
       1: invokespecial #13                 // Method java/lang/Object."<init>":()V                                                  
       4: aload_0                                                                                                                    
       5: aload_1                                                                                                                    
       6: putfield      #15                 // Field arg$1:Ljava/lang/String;                                                        
       9: return                                                                                                                     
                                                                                                                                     
  private static java.util.function.Supplier get$Lambda(java.lang.String);                                                           
    Code:                                                                                                                            
       0: new           #2                  // class ExampleWithCapturingLambda$$Lambda$1                                            
       3: dup                                                                                                                        
       4: aload_0                                                                                                                    
       5: invokespecial #19                 // Method "<init>":(Ljava/lang/String;)V                                                 
       8: areturn                                                                                                                    
                                                                                                                                     
  public java.lang.Object get();                                                                                                     
    Code:                                                                                                                            
       0: aload_0                                                                                                                    
       1: getfield      #15                 // Field arg$1:Ljava/lang/String;                                                        
       4: invokestatic  #28                 // Method ExampleWithCapturingLambda.lambda$main$0:(Ljava/lang/String;)Ljava/lang/String;
       7: areturn                                                                                                                    
}

It can be seen with the naked eye that the bytecode of the options with a method reference and the lambda that does not use a variable is identical, in both cases the constant pool is accessed. But if the lambda accesses a variable, then a field appears in the proxy class arg$1containing the value of the captured variable. Formally, this affects memory consumption, but if you are not going to generate millions of lambdas, then this influence can be neglected, especially at a time when even on mobile devices memory sizes are measured in gigabytes.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question