2017-08-24 69 views
0

我想在我的應用程序啓動過程中增加一些代碼和附加功能。整個設置本身工作正常,但有一點我認爲javassist可能會生成錯誤的代碼。Javassist似乎生成無效的字段訪問代碼

我正在做一個特定類的具體方法,我之前檢查,返回值實際上是類型StringBuilderStringBuffer

ctMethod.insertAfter("$_.SOME_METHOD(); $_.SOME_FIELD = <...>;"); 

SOME_METHOD()和SOME_FIELD在AbstractStringBuilder都聲明,的StringBuilderStringBuffer超類。兩者都被定義爲公共的,java.lang.AbstractStringBuilder本身只是包私有的。

操作本身是成功的,但執行此代碼會導致錯誤「java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class <...>」。通過打印調試,我發現,訪問該方法可以正常工作,但訪問該領域崩潰。

所以我檢查生成的字節碼:

... 
invokevirtual #41 <java/lang/StringBuilder.SOME_METHOD> 
... 
getfield #72 <java/lang/AbstractStringBuilder.SOME_FIELD> 
... 

因此,對於訪問它解析方法StringBuilder本身,但對於該領域其解析爲AbstractStringBuilder這顯然不是不從修改後的代碼的位置訪問。順便說一句,反編譯的字節碼看起來很好。

我也訪問這一領域在我的靜態代碼,所以我檢查這一項的字節碼:

... 
getfield #37 <java/lang/StringBuilder.SOME_FIELD> 
... 

這是代碼默認編譯器編譯,它不使用AbstractStringBuilder參考。

所以我的問題是:我監督了一些關於JVMs可見性和繼承的概念,或者javassist沒有正確地解決這個問題嗎? 我希望,我的解釋是可以理解的 - 否則讓我知道,我會盡力加強它。

回答

1

這是Javassist中的錯誤。

字段不是虛擬的,通過命名另一個類,您確實可以訪問需要由相關類訪問的不同(陰影)字段。

+0

好的,謝謝你的回答,我會在javassist項目中提出一個問題 - 或者你知道這個bug是否有一個? –

+1

不知道一個。 –