我想在编译时向某些类添加一个泛型字段。为了实现这个目标,我按照官方文档实现了我自己的 AST 注释和转换类,并使用 AST 注释注释了所需的类。
但是我在编译时得到了这个错误:
org . codehaus . groovy . control . multiplecompilationerrorsexception:启动失败:/home/.../groovy/Sample.groovy: -1:转换直接对字段x使用了包含ClassNode java.util.HashSet的泛型。你不应该这样做。请创建一个引用旧ClassNode的新ClassNode,并使用新ClassNode而不是旧class node。否则,编译器将在OpenJDK的TypeResolver中创建错误的描述符和潜在的NullPointerException。如果这不是你自己做的,请向转换的作者报告这个错误。@第1行,第1列。
我做错了吗?
示例代码
例如,假设我想添加一个< code>HashSet
我的 AST 注释类:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@GroovyASTTransformationClass(classes = [MyASTTransformation.class])
public @interface MyAST {
}
我的AST转换类:
@CompileStatic
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class MyASTTransformation implements ASTTransformation {
@Override
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
ClassNode clazz = (ClassNode) nodes[1];
ClassNode longHashSetClass = new ClassNode(HashSet.class);
longHashSetClass.setGenericsTypes([new GenericsType(new ClassNode(Long.class))] as GenericsType[]);
FieldNode field = new FieldNode("x", FieldNode.ACC_PRIVATE, longHashSetClass, clazz, new ConstantExpression(null));
clazz.addField(field);
}
}
带注释的类示例:
@MyAST
public class Sample {
}
当我删除行长哈希集类.set一般类型([新泛型类型(新类节点(长.class)]]作为泛型类型[]);
时,一切都很好,但x
的类型是哈希集
而不是哈希集
您应该使用ClassHelper或GenericUtils来创建ClassNode:
import static org.codehaus.groovy.ast.ClassHelper.make
import static org.codehaus.groovy.ast.tools.GenericsUtils.makeClassSafeWithGenerics
...
ClassNode hashSet = makeClassSafeWithGenerics(HashSet, make(Long))
问题内容: 在关于反射的本教程中,它指出: […]因为泛型是通过类型擦除实现的,因此在编译过程中会删除有关泛型类型的所有信息 我的知识是使用泛型,以便在编译时编译器可以检查类型安全性。即失败快速方法。但是该链接提到类型擦除会在编译期间删除通用信息。 问题答案: 您引用的语句是正确的:编译器在编译过程中在内部使用通用类型信息,在处理源时会生成与类型相关的错误。然后,一旦完成验证,编译器将生成类型擦除
以下代码: 给出编译器错误: 此行有多个标记-类型列表中的方法add(capture#1-of?extends String)不适用于参数(String)-方法add(capture#1-of?)类型列表中的不适用于参数(字符串) 是什么导致了这个错误?我应该不能添加Strings或它的子类型,因为我正在类型参数中扩展String吗?
问题内容: 有三种方法可以实现泛型: 只是用于编译时间检查的工具,但是每个模板实例都被编译为相同的字节/汇编代码实现(如注释“类型擦除”实现中所述的Java) 每个模板实例均被编译为专用代码(C ++,C#) #1和#2的组合 在Swift中实现哪一个? 问题答案: Swift首先会编译一个执行动态类型检查的实现,但是当速度与代码大小之间的权衡是有意义的时候,优化器可以选择为特定类型克隆专门的实现
问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用
问题内容: 我不得不发现我的项目中有Java代码,该代码可以在Eclipse中编译并正常运行,但是会在javac中引发编译错误。 一个完整的代码段: javac中的编译返回: 现在,此错误阻止在Maven中构建项目。由于Eclipse编译器具有更高的容忍度,因此我现在不得不假设代码段的定义和用法如上所述,静态方法不是有效的Java吗? 问题答案: 似乎Sun的1.6 JDK无法推断正确的类型。以下
我得到编译器错误在最后一行,我可以知道为什么吗?即使整数扩展了数字,我也会得到以下错误