2014-04-17 32 views
18

Tôi đang cố gắng tạo một ví dụ bằng cách sử dụng biểu thức lambda trong java và tôi đang sử dụng JDK8 chính thức. Ví dụ của tôi đã được chạy thành công. Nhưng khi tôi cố gắng để kiểm tra cách trình biên dịch dịch biểu thức lambda thành mã byte, điều này làm cho tôi một số confusion.Following là mã của ví dụ của tôi: -Cách biểu thức Lambda được dịch trong mã byte Java

public class LambdaTest { 
    public Integer lambdaBinaryOpertor(BinaryOperator<Integer> binaryOperator) { 
     return binaryOperator.apply(60, 72); 
    } 

    public static void main(String[] args) { 
     LambdaTest test = new LambdaTest(); 
     BinaryOperator<Integer> binaryOperator = (a, b) -> a*b; 
     System.out.println("Additon using Lambda BinaryOperator: "+test.lambdaBinaryOpertor(binaryOperator)); 
    } 
} 

Trong Article này, họ thảo luận về cách biên dịch dịch lambda biểu thức thành mã byte. Theo tài liệu này, biểu thức lambda chuyển đổi thành phương thức static và vị trí mà biểu thức lambda khai báo, có tham chiếu đến phương thức lambda static. Ví dụ sau nằm trong bài viết:

//Source code 
class A { 
    public void foo() { 
     List<String> list = ... 
     list.forEach(s -> { System.out.println(s); }); 
    } 
} 

//After compile above code "translate code " 
class A { 
    public void foo() { 
     List<String> list = ... 
     list.forEach([lambda for lambda$1 as Block]); 
    } 

    static void lambda$1(String s) { 
     System.out.println(s); 
    } 
} 

Ví dụ của tôi chạy tốt và cung cấp cho chúng tôi kết quả phù hợp. Nhưng khi tôi cố gắng chạy lệnh javap để kiểm tra mã byte của lớp, không có phương thức tĩnh cho lambdas trong mã byte.

c:\>javap LambdaTest 
Compiled from "LambdaTest.java" 
public class LambdaTest { 
public LambdaTest(); 
public java.lang.Integer lambdaBinaryOpertor(java.util.function.BinaryOperator <java.lang.Integer>); 
public static void main(java.lang.String[]); 
} 

Trong trường hợp của generics, phương pháp cầu được tạo ra bởi trình biên dịch và chúng tôi cũng sẽ kiểm tra phương pháp này sử dụng javap lệnh, nhưng trong trường hợp của lambdas không có phương pháp static. Bài báo đã được công bố tại năm 2012 và java 8 đã ra mắt tại cuộc diễu hành năm 2014. Vì vậy, tôi có một số thắc mắc liên quan đến xuyên quốc gia của lambda:

  1. Có thực mới được sử dụng cho lambda trong JDK 8 sau khi phát hành bài viết này hoặc tôi sẽ làm một cái gì đó sai để kiểm tra các phương pháp lambda?
  2. Thực sự trình biên dịch đối phó với biểu thức lambda như thế nào?
  3. Cách JVM gọi áp lực lambda?

Trả lời

17

Sử dụng javap lập luận thêm để in đầy đủ thông tin về lớp học: javap -v -p -s -c

Ví dụ, mã nguồn của lambda sẽ là:

private static java.lang.Integer lambda$main$0(java.lang.Integer, java.lang.Integer); 
    descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; 
    flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC 
    Code: 
     stack=2, locals=2, args_size=2 
     0: aload_0  
     1: invokevirtual #17     // Method java/lang/Integer.intValue:()I 
     4: aload_1  
     5: invokevirtual #17     // Method java/lang/Integer.intValue:()I 
     8: imul   
     9: invokestatic #2     // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
     12: areturn  
     LineNumberTable: 
     line 10: 0 
     LocalVariableTable: 
     Start Length Slot Name Signature 
      0  13  0  a Ljava/lang/Integer; 
      0  13  1  b Ljava/lang/Integer; 
} 
Các vấn đề liên quan