Decompiling java with JAD - limitations

ε祈祈猫儿з 提交于 2019-12-04 11:32:30

I think it's tableswitch for an enum. It translates the arbitrary enum ordinal value to number 0..n, it allows improve performance of the switch statement.

UPDATE Just understood it! The problem is - the code which uses the enum could be compiled separately from the enum itself. So it doesn't know at compile time the ordinal values, so it cannot construct a proper tableswitch op. So, that's why it introduces the lazy SWITCH_TABLE structure to map currently available ordinal values to the local tableswitch int numbers.

Looks to me like a switch statement on an enum. Take a look at the enum class, which enums implicitly extend. It has the ordinal method that's being used to switch over. There's probably some OrderType enum with constants LIMIT, MARKET, STOP and TAKE.

EDIT: Actually, I'm guessing some more info would be nice. There's some smoke and mirrors being used for stuff like enums. An enum constant gets some ordinal number behind the screens. This ordinal number is what's actually used in a bunch of constructs. When switching over an enum instance, the compiler actually creates a switch over an int (a well-known construct that's been around for a while) with the ordinal number as input.

What happens in your two code blocks is this: the first one sets up a "table" (actually just an array) for the enum ordinals if this didn't happen yet. There's a null check. If the table is null, it'll jump to label _L2 to do the priming. Otherwise, it jumps to label _L1 that simply returns. The second code block (the actualy switch statement) does a switch on an int. The int is obtained from the table by getting the element at the index that corresponds with the enum constant's ordinal number.

It seems a bit odd, but this forms some sort of indirection between the enum ordinals and the values used internally by the switch.

Now, the reason this all looks so low-level instead of simply seeing a switch on an enum is that enums were introduced in JDK 1.5, but JAD has been out of maintenance for a while and only really supports decompilation of source up to 1.4. Seeing how enums were implemented using constructs available in 1.4, the decompilation does actually work, but JAD has no knowledge of enums and as such doesn't make an effort to present this in a more legible manner.

Here's what that second code block probably looked like:

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;
}

When using the getDeclaredFields() method of the reflection API on Android, if the type being introspected contains an enum switch where the enum is declared in another class, one of the returned fields will be the lazy SWITCH_TABLE structure, called something like $SWITCH_TABLE$com$company$package$ClassName$EnumName.

I was using reflection to automatically map fields of a class to ContentValues before saving to the SQLite database, and just spent half a day on this trying to figure out why the array holding the column names was always off by one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!