我正在嘗試爲字節夥伴的字段創建一個「定製」setter方法。 Buddy自己的機制允許非常容易地實現標準的setter/getter方法,但是,我正在尋找一種優雅的方式來擴展setter和一些額外的邏輯。Java字節代碼:與字節夥伴的定製setter/getter
爲了簡化示例,我們假設我們有一個類A,它有一個方法setChanged(String)。 目標是創建A的子類,並添加一個具有相應訪問方法的字段。 問題在於,我想從每個添加的setter方法中調用setChanged(「fieldName」)。
public void setName(String name)
{
setChanged("name");
this.name = name;
}
對於一個 「正常」 的setter方法,字節byddy實現是:我
new ByteBuddy()
.subclass(A.class)
.name("B")
.defineField("name", Integer.TYPE, Visibility.PUBLIC)
// args is a ArrayList<Class<?>>
.defineMethod(getSetterName(name), Void.TYPE, args, Visibility.PUBLIC)
.intercept(FieldAccessor.ofField(name))
字節碼看起來像這樣經過:
L0
ALOAD 0 // Loads the this reference onto the operand stack
ILOAD 1 // Loads the integer value of the local variable 1 (first method arg)
PUTFIELD package/B.name : I // stores the value to the field
L1
ALOAD 0
LDC "name"
INVOKEVIRTUAL package/A.setChanged (Ljava/lang/String;)V
RETURN
我的問題是:有沒有在這種情況下重新使用FieldAccessor的方法?
我不確定你真正的問題是什麼。你想知道是否可以將FieldAccessor.ofField(...)'的結果存儲到一個變量中並多次使用它?你爲什麼不嘗試它?或者你的意思是什麼樣的重用? – Holger 2014-10-29 14:57:40
嗨Holger, 我想用方法調用擴展FieldAccessor.ofField(...)(在上面的例子中:setChanged(「name」);)。 我的意思是重複使用代碼,而不是對象。基本上(這可能是錯誤的方法),我想獲得FieldAccessor的堆棧操作並在另一個複合堆棧操作中使用它。 – 2014-10-30 08:23:57
呃,有['Instrumentation.Compound'](http://bytebuddy.net/javadoc/0.3.1/net/bytebuddy/instrumentation/Instrumentation.Compound.html#Compound-net.bytebuddy.instrumentation.Instrumentation ... - ),但奇怪的是,我沒有找到任何方式來調用'this'上的另一種方法... – Holger 2014-10-30 10:01:19