2012-12-29 31 views
1

我正在使用ASM攔截所有嘗試在目標應用程序中突變字段值,因爲ASM允許您在方法或構造函數代碼段中預加或附加指令。ASM - 在外部進行攔截字段訪問方法

但是,它發生,我認爲它是一個相當普遍的開發模式初始化一個方法或構造例如範圍之外的領域:

public class Example{ 

    //--VARIABLE INITIALIZATION OUTSIDE METHOD OR CONSTRUCTOR SCOPE --- 
    private String aString = "A String Value"; 

    //zero argument constructor 
    public Example(){ 

    } 

    //all other methods. 


} 

我的問題是:如何將一個接近攔截任務以這種方式進行字段訪問,即在方法或構造器的上下文之外?

回答

2

這看起來像它在源代碼中的構造函數外,但實際上在字節碼的初始化是構造(或多個)的一部分 - 他們得到由編譯器「移動」到構造函數中。初始化程序被放置在之後隱式或顯式的super()調用但是之前其餘的構造函數的代碼。具體而言,這意味着,如果你有這樣的情況:

class Super { 
    protected Super() { 
    doSomeStuff(); 
    } 

    protected abstract void doSomeStuff(); 
} 

class Sub extends Super { 
    private int number = 1; 

    public Sub() { 
    super(); 
    System.out.println("in Sub(): " + number); 
    } 

    protected doSomeStuff() { 
    System.out.println("in doSomeStuff(): " + number); 
    } 
} 

然後new Sub();將打印

in doSomeStuff(): 0 
in Sub(): 1 

Sub字段初始運行之前的in doSomeStuff打印發生。

+0

非常感謝您爲我解決這個問題。 –

+0

您對於如何在子類上下文中工作的更多見解也非常感謝。謝謝。 –

1

所有代碼都在裏面的方法(構造函數和靜態初始化器也是方法)。

您有字段的初始值,您可以在字段聲明中看到,但編譯器似乎沒有使用太多。

private String aString = "A String Value"; 

//zero argument constructor 
public Example(){ 

} 

相同

private String aString; 

//zero argument constructor 
public Example(){ 
    super(); 
    aString = "A String Value"; 
} 
+0

出於某種原因,我認爲這是由一些隱藏的初始化塊。感謝您澄清這一點 - 當然,您是正確的。 –

+1

在ASM中,構造函數被稱爲'(...)V',並且靜態初始化塊被稱爲'()V' –