Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Java 8 Lambda principle analysis     - Android Studio Personalization (Linux)

- 7 JavaScript interview questions (Programming)

- Python 2 Chinese garbage problem solved (Linux)

- MongoDB Installation under CentOS 6.6 (Database)

- Try the command ip, ifconfig is obsolete under Linux (Linux)

- Android memory optimization of the optimal load Bitmap (Linux)

- Go constructed using an interpreted language (Programming)

- Linux kernel source tree to establish load module hello (Linux)

- Nine artifact control disk partition under Linux (Linux)

- MD5 and simple to use (Linux)

- Object Oriented Programming Java reflection (Programming)

- Use Ganglia to monitor your cluster (Server)

- How to install web crawler tool in Ubuntu 14.04 LTS: Scrapy (Linux)

- Linux operating system log system (Linux)

- Java in the final qualifier (Programming)

- To install HDRMerge 0.4.3 under ubuntu (Linux)

- After installation of Debian 6.0 do a few things first (Linux)

- How do I cancel (almost) any operations in Git, (Linux)

- Tree Traversals Again (Programming)

- Linux Programming memory mapping (Programming)

 
         
  Java 8 Lambda principle analysis
     
  Add Date : 2017-04-13      
         
         
         
  To support functional programming, Java 8 introduced Lambda expressions, then in the end is how to achieve Lambda expressions in Java 8 in it? Lambda expressions compiled after, in the end will generate what is it? In the absence of in-depth analysis, let let's think about it, Java 8 each Lambda expression must have a corresponding interface function, difference function interface and common interface, you can refer to the previous content, then you probably think Lambda expressions are not transformed a corresponding function interface of a class that implements it, and then call the subclass by a multi-state approach it, code like the following is an example of a Lambda expressions

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}
public class Lambda {
    public static void PrintString (String s, Print < String> print) {
        print.print (s);
    }
    public static void main (String [] args) {
        PrintString ( "test", (x) -> System.out.println (x));
    }
}

According to the above analysis, in theory, after the compiler handles the resulting code should look like the following:

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}

class Lambda $$ 0 implements Print < String> {
    @Override
    public void print (String x) {
        System.out.println (x);
    }
}

public class Lambda {
    public static void PrintString (String s,
            Print < String> print) {
        print.print (s);
    }
    public static void main (String [] args) {
        PrintString ( "test", new Lambda $$ 0 ());
    }
}

Or again is an internal class implementation code as follows:

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}
public class Lambda {
    final class Lambda $$ 0 implements Print < String> {
        @Override
        public void print (String x) {
            System.out.println (x);
        }
    }
    public static void PrintString (String s,
            Print < String> print) {
        print.print (s);
    }
    public static void main (String [] args) {
        PrintString ( "test", new Lambda () new Lambda $$ 0 ().);
    }
}

Such exclusive or anonymous inner class, the code is as follows:

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}
public class Lambda {
    public static void PrintString (String s,
            Print < String> print) {
        print.print (s);
    }
    public static void main (String [] args) {
        PrintString ( "test", new Print < String> () {
            @Override
            public void print (String x) {
                System.out.println (x);
            }
        });
    }
}

The above code, in addition to sprinkling in code length, the code runs with the results achieved with Lambda expressions are the same, then the Java 8 in the end what is the way to achieve it? Is not the above three implementations of a kinds of it, you may feel their own thinking is, in fact, that would have been right, in 8 Java class is used internally to implement Lambda expressions

So Lambda expression in the end is how to achieve it?

To explore Lambda expressions is how to achieve, you have to be studied Lambda Table-through eventually converted into a byte code file, which is a bytecode needs jdk bin directory under the viewer and decompiler

javap -p Lambda.class

The above command -p represents the output of all classes and members, run the above command, the results obtained are as follows:

Compiled from "Lambda.java"
public class Lambda {
  public Lambda ();
  public static void PrintString (java.lang.String, Print < java.lang.String>);
  public static void main (java.lang.String []);
  private static void lambda $ 0 (java.lang.String);
}

As can be seen from the above code compiler generates a private static function according to Lambda expressions, note, to say here is generated, rather than the equivalent

private static void lambda $ 0 (java.lang.String);

? In order to verify the above conversion is correct, we define a lambda $ 0 this function in your code, the final code is as follows:

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}

public class Lambda {
    public static void PrintString (String s,
            Print < String> print) {
        print.print (s);
    }
    private static void lambda $ 0 (String s) {
    }
    public static void main (String [] args) {
        PrintString ( "test", (x) -> System.out.println (x));
    }
}

The above code will not compile-time error, but the error will run, because there are two lambda $ 0 function, as shown below, is a run-time error

Exception in thread "main" java.lang.ClassFormatError: Duplicate method name & signature in class file Lambda
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:760)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:467)
    at java.net.URLClassLoader.access $ 100 (URLClassLoader.java:73)
    at java.net.URLClassLoader $ 1.run (URLClassLoader.java:368)
    at java.net.URLClassLoader $ 1.run (URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:424)
    at sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:331)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:357)
    at sun.launcher.LauncherHelper.checkAndLoadMain (LauncherHelper.java:495)

By javap the above error code to decompile, decompile output after members of the class as follows

Compiled from "Lambda.java"
public class Lambda {
  public Lambda ();
  public static void PrintString (java.lang.String, Print < java.lang.String>);
  private static void lambda $ 0 (java.lang.String);
  public static void main (java.lang.String []);
  private static void lambda $ 0 (java.lang.String);
}

Find lambda $ 0 appears twice, at the time the code is running, do not know what to call, so the error will be thrown.

With the above content, you can know is that Lambda expressions in Java 8 will be the first to generate a private static function, this private static function is Lambda expressions inside dry content, so the above code can be converted into the following preliminary the code shown

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}
public class Lambda {
    public static void PrintString (String s, Print < String> print) {
        print.print (s);
    }
    
    private static void lambda $ 0 (String x) {
        System.out.println (x);
    }
    
    public static void main (String [] args) {
        PrintString ( "test", / ** lambda expression ** /);
    }
}

After transforming into the form above, then how to call the static lambda $ 0 it functions, where the breakpoint can be marked in the following methods can be found in the place where there is a lambda expression, the function will enter the run-time

 public static CallSite metafactory (MethodHandles.Lookup caller,
                                      String invokedName,
                                      MethodType invokedType,
                                      MethodType samMethodType,
                                      MethodHandle implMethod,
                                      MethodType instantiatedMethodType)
            throws LambdaConversionException {
        AbstractValidatingLambdaMetafactory mf;
        mf = new InnerClassLambdaMetafactory (caller, invokedType,
                                            invokedName, samMethodType,
                                            implMethod, instantiatedMethodType,
                                            false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
        mf.validateMetafactoryArgs ();
        return mf.buildCallSite ();
}

In this function can be found for the Lambda expressions to generate an internal class, in order to verify whether to generate an internal class, you can add -Djdk.internal.lambda.dumpProxyClasses at run time, add this parameter, run time, will generate inner class class code output to a file

final class Lambda $$ Lambda $ 1 implements Print {
  private Lambda $$ Lambda $ 1 ();
  public void print (java.lang.Object);
}

If you run javap -c -p result is as follows

final class Lambda $$ Lambda $ 1 implements Print {
  private Lambda $$ Lambda $ 1 ();
    Code:
      0: aload_0
      1:. Invokespecial # 10 // Method java / lang / Object "< init>" :() V
      4: return

  public void print (java.lang.Object);
    Code:
      0: aload_1
      1: checkcast # 14 // class java / lang / String
      4: invokestatic # 20 // Method Lambda.lambda $ 0: (Ljava / lang / String;) V
      7: return
}

Through the above byte code instructions can be found on the realization of the call is Lambda.lambda $ 0 This private static method

So the final Lambda expression is equivalent to the following form

@FunctionalInterface
interface Print < T> {
    public void print (T x);
}
public class Lambda {
    public static void PrintString (String s, Print < String> print) {
        print.print (s);
    }
    private static void lambda $ 0 (String x) {
        System.out.println (x);
    }
    final class $ Lambda $ 1 implements Print {
        @Override
        public void print (Object x) {
            lambda $ 0 ((String) x);
        }
    }
    public static void main (String [] args) {
        PrintString (. "Test", new Lambda () new $ Lambda $ 1 ());
    }
}
     
         
         
         
  More:      
 
- Oracle11g CRS-0184 Problem Solving (Database)
- The first IOS Objective-C program (Programming)
- Zabbix monitors the status of TCP connections (Server)
- Btrfs file system repair techniques (Linux)
- CentOS 6.4 Python 2.6 upgrade to 2.7 (Linux)
- Implement binary search algorithm in C language (Programming)
- Boost notes --Asio - (1) a simple small example of synchronous communication (Programming)
- Oracle multi-table query optimization (Database)
- HomeKit Human Interface Guidelines (Linux)
- HTTP and HTTPS request response process difference (Linux)
- Golang use Oracle database on Ubuntu 14.04 (Linux)
- impdp error ORA-39001, ORA-39000, ORA-31619 (Database)
- MySQL enabled SSD storage (Database)
- Linux more efficient than select a model epoll (Linux)
- Processor in protected mode of protection (Linux)
- Ubuntu Tutorial: E: Failed to get lock / var / lib / apt / lists / lock - open (Linux)
- To_explore Linux system boot process (Linux)
- How to install Git on CentOS 7 (Linux)
- Construction CA certificate using OpenSSL command line (Server)
- Configuration OpenOCD + FT2232 under Ubuntu (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.