我們可以像下面的代碼一樣聲明字段。將字段聲明爲參數化列表使用java assist
evalClass.addField(CtField.make("private java.util.List abc;", evalClass));
如何使用java assist聲明域List<String> abc
?
我們可以像下面的代碼一樣聲明字段。將字段聲明爲參數化列表使用java assist
evalClass.addField(CtField.make("private java.util.List abc;", evalClass));
如何使用java assist聲明域List<String> abc
?
完成對CtField類的一點研究。我們可以通過setGenericSignature來設置。
CtField f = new CtField(pool.get(List.class.getCanonicalName()), "abc", evalClass);
f.setGenericSignature(getGenericSignature(relatedClass));
evalClass.addField(f);
private String getGenericSignature(Class relatedClass) throws BadBytecode {
String fieldSignature = "L" + List.class.getCanonicalName().replace(".", "/") + "<L" + String.class.getCanonicalName().replace(".", "/") + ";>;";
return SignatureAttribute.toClassSignature(fieldSignature).encode();
}
首先,Javassist不支持泛型。 從Javassist進行documentation:
泛型
了Javassist的較低級別的API完全支持泛型通過 爪哇5.引入在另一方面,更高級別的API諸如CtClass確實 不直接支持仿製藥。但是,對於字節碼轉換,這不是一個嚴重的問題 。
Java的泛型是通過擦除技術實現的。在編譯 之後,所有類型參數都將被刪除。例如,假設 你的源代碼聲明一個參數的類型爲向量:
Vector<String> v = new Vector<String>(); String s = v.get(0);
編譯的字節碼是等同於以下代碼:
Vector v = new Vector(); String s = (String)v.get(0);
所以,當你 寫字節碼轉換,你可以放棄所有類型的 參數。由於Javassist中嵌入的編譯器不支持,支持泛型,因此如果源代碼由Javassist編譯,例如通過 CtMethod.make(),則必須在調用者 站點處插入明確的類型轉換。如果源代碼是由普通Java編譯器(如javac)編譯的 ,則不需要進行類型轉換。
所以你基本上可以利用你在你的問題刨光的方法,以添加列表不一般規範,這就是會做的工作