2011-10-24 3 views
4

Java에서 JAD를 사용하여 몇 개의 jar 파일을 디 컴파일하려고합니다. (JD-GUI도 적게 사용했지만) 많은 오류가 발생합니다. 한 종류 (쉽게 고칠 수) 내부 클래스와 것 같다, 그러나 나는 또한 코드의이 비트 발견로 사용JAD에서 Java 디 컴파일 - 제한

static int[] $SWITCH_TABLE$atp$com$OrderType() 
{ 
    $SWITCH_TABLE$atp$com$OrderType; 
    if($SWITCH_TABLE$atp$com$OrderType == null) goto _L2; else goto _L1 
_L1: 
    return; 
_L2: 
    JVM INSTR pop ; 
    int ai[] = new int[OrderType.values().length]; 
    try 
    { 
     ai[OrderType.LIMIT.ordinal()] = 2; 
    } 
    catch(NoSuchFieldError _ex) { } 
    try 
    { 
     ai[OrderType.MARKET.ordinal()] = 1; 
    } 
    catch(NoSuchFieldError _ex) { } 
    try 
    { 
     ai[OrderType.STOP.ordinal()] = 3; 
    } 
    catch(NoSuchFieldError _ex) { } 
    try 
    { 
     ai[OrderType.TAKE.ordinal()] = 4; 
    } 
    catch(NoSuchFieldError _ex) { } 
    return $SWITCH_TABLE$atp$com$OrderType = ai; 
} 

는 다음을 :

switch($SWITCH_TABLE$atp$com$OrderType()[co.getOrderType().ordinal()]) 
     { 
     case 1: // '\001' 
      order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker); 
      break; 

     case 2: // '\002' 
      order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderPrice(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker); 
      break; 

     case 3: // '\003' 
      order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderPrice(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker); 
      break; 
     } 

어떤 생각 어떤이 구조 원래 수 있었 니?

답변

5

열거 형의 switch 문처럼 보입니다. 암시 적으로 확장되는 enum 인 enum class을 살펴보십시오. 전환하는 데 사용되는 ordinal 메소드가 있습니다. LIMIT, MARKET, STOP 및 TAKE 상수가있는 OrderType 열거 형이있을 수 있습니다.

편집 : 실제로, 나는 더 많은 정보가 좋을 것 같아요. enum과 같은 것들에 사용되는 연기와 거울이 있습니다. 열거 형 상수는 화면 뒤에 서수를 얻습니다. 이 순서 번호는 실제로 여러 구성 요소에서 사용되는 번호입니다. enum 인스턴스를 전환 할 때 컴파일러는 실제로 서수를 입력으로 사용하여 int (잠시 동안 있었던 잘 알려진 구문)에 대한 스위치를 만듭니다.

두 코드 블록에서 일어나는 일은 다음과 같습니다. 첫 번째 것은 아직 열거되지 않은 경우 열거 형 서수에 대한 "테이블"(실제로는 단지 배열)을 설정합니다. 널 체크가 있습니다. 테이블이 null의 경우, 프라이밍을 실시하기 위해서 라벨 _L2에 점프합니다. 그렇지 않으면 간단히 리턴하는 _L1 레이블로 점프합니다. 두 번째 코드 블록 (실제 switch 문)은 int에서 스위치를 수행합니다. int는 열거 형 상수의 서수와 일치하는 색인에서 요소를 가져 와서 테이블에서 가져옵니다.

다소 이상하게 보일 수 있지만 이것은 열거 형 서수와 스위치가 내부적으로 사용하는 값 ​​사이에 어떤 종류의 간접 지정을 형성합니다.

enum이 JDK 1.5에 도입되었지만 JAD가 잠시 동안 유지 관리를 마쳤고 소스의 역 컴파일 만 지원한다는 점에서이 모든 것이 열거 형에서 스위치를 보는 대신 저급 인 것처럼 보이는 이유가 있습니다. 최대 1.4 1.4에서 사용 가능한 구조체를 사용하여 열거 형을 구현 한 방법을 보면 디 컴파일은 실제로 작동하지만 JAD는 열거 형에 대한 지식이 없으므로이를보다 쉽게 ​​읽을 수있는 방법으로 제시하지 않습니다. 나는 그것을 열거에 대한 tableswitch 생각

switch(co.getOrderType()) { //co.getOrderType() gets the OrderType of some variable 
    case MARKET : order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker); 
        break; 
    case LIMIT : order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderPrice(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker); 
       break; 
    case STOP : order = new Order(userID, null, co.getOrderType(), co.getOrderSide(), co.getOrderPrice(), co.getOrderID(), co.getOrderSecurity(), co.getOrderQuantity(), broker); 
       break; 
} 
+0

왜 내가 테이블을 만들고 그냥 enum의 서수를 직접 사용하지 않는지 궁금해합니다. (그들은 이미'int's입니까?) – kan

+0

좋아, 이제 이해, 설명과 함께 내 대답을 업데이 트되었습니다. – kan

7

: 같은

다음은 그 두 번째 코드 블록은 아마 속입니다. 임의의 enum ordinal 값을 number 0..n으로 변환하면 switch 문의 성능을 향상시킬 수 있습니다.

업데이트 그냥 이해했습니다. 문제는 열거 형을 사용하는 코드를 열거 형과 별도로 컴파일 할 수 있다는 것입니다. 따라서 컴파일 타임에 순서 값을 알 수 없으므로 적절한 테이블 스위치를 구성 할 수 없습니다. 그래서, 현재 사용 가능한 서수 값을 로컬 테이블 스위치 int 수에 매핑하는 게으른 SWITCH_TABLE 구조를 도입 한 것입니다.

+0

좋은 공연! 이 간접 참조를 도입하는 이유를 알지 못했지만 완벽하게 설명합니다. –

0

Android에서 리플렉션 API의 getDeclaredFields() 메소드를 사용할 때, introspect되는 유형에 다른 클래스에서 enum이 선언 된 enum 스위치가 포함되어 있으면 반환되는 필드 중 하나가 게으른 SWITCH_TABLE 구조입니다 $SWITCH_TABLE$com$company$package$ClassName$EnumName입니다.

리플렉션을 사용하여 클래스의 필드를 ContentValues에 SQLite 데이터베이스에 저장하기 전에 자동으로 매핑하고 열 이름을 포함하는 배열이 항상 하나씩 꺼져있는 이유를 알아 내기 위해 반나절을 보냈습니다.