2014-09-13 2 views
11
import java.io.*;    
import java.net.*;    

public class Test {   
    public static void main(String[] arguments) throws Exception { 
     Runnable runnable =() -> { 
      try { 
       throwException(); 
      } 
      catch (SocketException|EOFException exception) { 
       System.err.println("wrong"); 
      } 
      catch (IOException exception) { 
       System.err.println("right"); 
      } 
     }; 

     runnable.run(); 
    }       

    private static void throwException() throws IOException { 
     throw new NotSerializableException(); 
    }       
} 

왜이 프로그램이 "잘못"인쇄합니까? 람다를 제거하거나 멀티 캐치 절을 깨면 "right"가 인쇄됩니다.lambdas와 multi-catch 절을 결합 할 때 Java 버그가 있습니까?

$ javac -version 
javac 1.8.0_11 
$ java -version 
java version "1.8.0_11" 
Java(TM) SE Runtime Environment (build 1.8.0_11-b12) 
Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode) 

답변

11

이 1.8.0_11에서 1.8.0_20에서 fixed bug이었다

지역 : 도구/javac의
시놉시스 : javac의 람다 내부 다중 catch 문에 대한 잘못된 예외 테이블을 생성

람다 안에서 여러 캐치가있는 try-catch 처리가 수정되었습니다. 번역과의 매핑 동안

LTM은 삭제 (의 무거운 사용한다) :

실제 버그 리포트 실제로 잘못 무엇 JDK-8036942

컴파일러 내에서 가정 형 정보 손실이었다입니다 변수. 이러한 삭제 작업은 대부분의 경우 정확할 수 있지만이 경우에 정보 손실이 발생할 수 있습니다. 또한 대부분의/모든 유형을 삭제해야하는 TransType 뒤에 LTM이 적용되므로 erasure()를 사용하는 것이 필요합니다. TransTypes의 버그 일 수 있는지 궁금합니다. 나는 이것이 LTM의 현재 관리자 인 Robert Field에 의해 평가되어야한다고 생각합니다. 여기서 가장 좋은 접근 방법은 무엇입니까? 그러면 나는 그에게 다시 할당 할 것입니다. 내가 8u20에 표시되는 내용

는 (I 명령 줄 매개 변수를 제공하는 것을 잊었다 더 이상 제대로 할 8u20가) :

wlan1-loopback% /usr/lib/jvm/java-8-oracle/bin/javap -c Test 
Compiled from "Test.java" 
public class Test { 
    public Test(); 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: return 

    public static void main(java.lang.String[]) throws java.lang.Exception; 
    Code: 
     0: invokedynamiC#2, 0    // InvokeDynamiC#0:run:()Ljava/lang/Runnable; 
     5: astore_1 
     6: aload_1 
     7: invokeinterface #3, 1   // InterfaceMethod java/lang/Runnable.run:()V 
     12: return 
} 
wlan1-loopback% java Test 
right 
wlan1-loopback% java -version 
java version "1.8.0_20" 
Java(TM) SE Runtime Environment (build 1.8.0_20-b26) 
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode) 
wlan1-loopback% 

올바른 :

public class Test { 
    public Test(); 
    descriptor:()V 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: return 

    public static void main(java.lang.String[]) throws java.lang.Exception; 
    descriptor: ([Ljava/lang/String;)V 
    Code: 
     0: invokedynamiC#2, 0    // InvokeDynamiC#0:run:()Ljava/lang/Runnable; 
     5: astore_1 
     6: aload_1 
     7: invokeinterface #3, 1   // InterfaceMethod java/lang/Runnable.run:()V 
     12: return 

    private static void throwException() throws java.io.IOException; 
    descriptor:()V 
    Code: 
     0: new   #4     // class java/io/NotSerializableException 
     3: dup 
     4: invokespecial #5     // Method java/io/NotSerializableException."<init>":()V 
     7: athrow 

    private static void lambda$main$0(); 
    descriptor:()V 
    Code: 
     0: invokestatic #6     // Method throwException:()V 
     3: goto   27 
     6: astore_0 
     7: getstatic  #9     // Field java/lang/System.err:Ljava/io/PrintStream; 
     10: ldc   #10     // String wrong 
     12: invokevirtual #11     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     15: goto   27 
     18: astore_0 
     19: getstatic  #9     // Field java/lang/System.err:Ljava/io/PrintStream; 
     22: ldc   #13     // String right 
     24: invokevirtual #11     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     27: return 
    Exception table: 
     from to target type 
      0  3  6 Class java/net/SocketException 
      0  3  6 Class java/io/EOFException 
      0  3 18 Class java/io/IOException 
} 
10

이 버그는 내가 1.8.0_11 그것을 복제 할 수 있어요 1.8.0_20 https://bugs.openjdk.java.net/browse/JDK-8036942

로 고정되어 있으며 1.8.0_20

$ javac -version 
javac 1.8.0_11 
$ java -version 
java version "1.8.0_11" 
Java(TM) SE Runtime Environment (build 1.8.0_11-b12) 
Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode) 
$ javac Test.java 
$ java Test 
wrong 

잘 작동 으로 고정

~$ javac -version 
javac 1.8.0_20 
$ javac Test.java 
$ java -version 
java version "1.8.0_20" 
Java(TM) SE Runtime Environment (build 1.8.0_20-b26) 
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode) 
$ java Test 
right