繁体   English   中英

使用Java辅助将字段声明为参数化列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM