[英]Declare Field as Parameterized List Using java assist
我们可以像下面的代码一样声明字段。
evalClass.addField(CtField.make("private java.util.List abc;", evalClass));
我们如何使用Java辅助声明字段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 文档中 :
泛型
Javassist的较低级API完全支持Java 5引入的泛型。另一方面,较高级的API(如CtClass)不直接支持泛型。 但是,这对于字节码转换不是一个严重的问题。
Java的泛型是通过擦除技术实现的。 编译后,所有类型参数均被删除。 例如,假设您的源代码声明了一个参数化类型Vector:
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)编译的,则无需类型转换。
因此,您基本上可以使用在问题中使用的方法来添加没有通用规范的列表,这样就可以完成工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.