简体   繁体   English

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

[英]Declare Field as Parameterized List Using java assist

We can declare field like following code. 我们可以像下面的代码一样声明字段。

evalClass.addField(CtField.make("private java.util.List abc;", evalClass));

How can we declare field List<String> abc using java assist? 我们如何使用Java辅助声明字段List<String> abc

Done little bit research on CtField class. 关于CtField类的研究很少。 we can set through setGenericSignature. 我们可以通过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();
    }

First, generics are not supported by Javassist. 首先,Javassist不支持泛型。 From the Javassist documentation : 从Javassist 文档中

Generics 泛型

The lower-level API of Javassist fully supports generics introduced by Java 5. On the other hand, the higher-level API such as CtClass does not directly support generics. Javassist的较低级API完全支持Java 5引入的泛型。另一方面,较高级的API(如CtClass)不直接支持泛型。 However, this is not a serious problem for bytecode transformation. 但是,这对于字节码转换不是一个严重的问题。

The generics of Java is implemented by the erasure technique. Java的泛型是通过擦除技术实现的。 After compilation, all type parameters are dropped off. 编译后,所有类型参数均被删除。 For example, suppose that your source code declares a parameterized type Vector: 例如,假设您的源代码声明了一个参数化类型Vector:

 Vector<String> v = new Vector<String>(); String s = v.get(0); 

The compiled bytecode is equivalent to the following code: 编译后的字节码等效于以下代码:

 Vector v = new Vector(); String s = (String)v.get(0); 

So when you write a bytecode transformer, you can just drop off all type parameters. 因此,当您编写字节码转换器时,可以删除所有类型参数。 Because the compiler embedded in Javassist does not support generics , you must insert an explicit type cast at the caller site if the source code is compiled by Javassist, for example, through CtMethod.make(). 因为嵌入在Javassist中的编译器不支持泛型 ,所以如果源代码是由Javassist编译的,例如通过CtMethod.make(),则必须在调用者站点插入一个显式类型强制转换。 No type cast is necessary if the source code is compiled by a normal Java compiler such as javac. 如果源代码是由普通的Java编译器(如javac)编译的,则无需类型转换。

So you can basically use the method you wrot in your question in order to add a List without generic specification and that's gonna do the work 因此,您基本上可以使用在问题中使用的方法来添加没有通用规范的列表,这样就可以完成工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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