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

时间:2017-06-21 11:22:13

标签: java javassist

我们可以像下面的代码一样声明字段。

# This sets the install path when you do `crystal deps`.
# It needs to be an absoluete path, not a relative path.
export SHARDS_INSTALL_PATH="$PWD/my/dir" 

# This is needed for the Crystal compiler to the find the shards.
#  The Crystal compiler does not use SHARDS_INSTAL_PATH.
#  Unlike SHARDS_INSTALL_PATH, it can be a relative path.
#  You must also specify the place for the Crystal source directory
#  in order to find the Standard Lib .cr files:
export CRYSTAL_PATH="$SHARDS_INSTALL_PATH:the/crystal/src"

# Now you can do:
crystal deps                  # uses SHARDS_INSTALL_PATH
crystal build src/my-file.cr  # uses CRYSTAL_PATH

我们如何使用java辅助声明字段evalClass.addField(CtField.make("private java.util.List abc;", evalClass));

2 个答案:

答案 0 :(得分:0)

对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();
    }

答案 1 :(得分:0)

首先,Javassist不支持泛型。 来自Javassist documentation

  

<强>泛型

     

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。

所以你基本上可以在你的问题中使用你想要的方法,以便添加一个没有通用规范的List,那将会完成工作