【问题标题】:Java Dynamic Code Generation with support for generics支持泛型的 Java 动态代码生成
【发布时间】:2011-04-05 12:48:15
【问题描述】:

有没有提供Java动态代码生成并且还支持泛型的工具?

例如,Javassist 是我需要的那种工具,但它不支持泛型。

我编写了一个使用 Java 6 Compiler API 的小库,但据我所知,它依赖于 JDK。有没有办法指定另一个编译器?还是仅将我需要使用 Java Compiler API 调用的部分随我的应用程序一起提供?

【问题讨论】:

  • 只是出于好奇:“不支持泛型”到底是什么意思?这对您来说有什么问题?我想你可以用原始类型做所有事情?
  • Javassist 不支持泛型类型。因此我无法编译泛型类。虽然我可以对对象和强制转换做同样的事情,但对于我正在做的事情来说,手头有泛型类型确实很有帮助。
  • 如果我理解正确的话,类型擦除过程或多或少地将源代码中的泛型替换为对象并转换为字节码。字节码级别不存在泛型。

标签: java-compiler-api java dynamic-code


【解决方案1】:

看来您可以使用 Javaassist 操作和读取通用信息。见

http://www.mail-archive.com/jboss-user@lists.jboss.org/msg101222.html

[jboss-user] [Javassist 用户问题] - Re: Altering Generics Information of Methods using Javassist 西蒙林格特 2007 年 12 月 20 日星期四 12:22:14 -0800

我已经进一步阅读了编译器是如何实现的,并且 终于找到了我想要的答案。

您绝对可以使用 javaassist 做到这一点。关键类是 javassist.bytecode.SignatureAttribute.

从 CtMethod 中,我获得了添加 Signature 属性的 methodInfo。你可以这样做:

CtMethod method = ....
   MethodInfo methodInfo = method.getMethodInfo();
   SignatureAttribute signatureAttribute = new 
SignatureAttribute(methodInfo.getConstPool(),
   "()Ljava/util/List<Ljava/lang/String;>;");
   methodInfo.addAttribute(signatureAttribute);

如果您对阅读带有泛型的签名更感兴趣,您 可以使用方法Info.getAttribute(SignatureAttribute.tag)。

我希望这会有所帮助。

【讨论】:

  • 我已经玩过很多次了,Javassist 使用泛型生成的代码非常适合 JAXB 和 Jackson 序列化。只需为任一格式添加正确的注释和通用信息。这在嵌套数组要序列化时特别有用,因为 Java 完全失去了嵌套结构(如 List>)的类型信息。相反,可以发出 List 其中 ListOfLong 是具有长成员的特殊 List 实现。
【解决方案2】:

如果您对编写字节码感到满意,那么ASM 是一个非常好的库。这将使您可以即时生成类文件,而不必担心类文件格式的细节。然后,您可以使用类加载器将其动态加载到您的应用程序中。

【讨论】:

    【解决方案3】:

    如果我没记错的话,在类路径中有 tools.jar 就足够了,以便在运行时使用 Java 编译器。

    【讨论】:

    • 谢谢,明天我会对此进行一些测试并回复。
    【解决方案4】:

    其实javaassist可以使用SignatureAttribute处理泛型。

    SignatureAttribute.Type retType = new SignatureAttribute.BaseType(Void.TYPE.getName());
    SignatureAttribute.Type[] argType = getArgType();
    SignatureAttribute.MethodSignature signature = new SignatureAttribute.MethodSignature(null, argType, retType, null);
    method.setGenericSignature(signature.encode());
    

    This project 有很多很好的例子。希望他们有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 2017-06-24
      • 2010-12-17
      • 2015-04-04
      相关资源
      最近更新 更多