我们可以像下面的代码一样声明字段。
# 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));
?
答案 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,那将会完成工作