【问题标题】:Does groovy @CompileStatic imply @TypeChecked?groovy @CompileStatic 是否暗示 @TypeChecked?
【发布时间】:2019-04-16 23:28:54
【问题描述】:

我一直在将 @TypeChecked@CompileStatic 添加到 groovy 代码中。

编译器接受这个,但它是多余的吗? TypeChecked 是否添加了 CompileStatic 没有添加的任何内容?文档似乎暗示 CompileStatic 是一个超集,但没有直接这么说。我想在偶尔禁用严格类型检查的同时进行静态编译,让 groovy 自动类型转换,同时仍然捕获拼写错误的引用或丢失的方法。

一个例子:

@TypeChecked
@CompileStatic
class MyClass {
    void simple() {
        // compiles fine statically
    }

    @TypeChecked(SKIP)
    void complicated() {
        // would require too many ugly typecasts
    }

    @CompileDynamic
    void evenworse() {
        // need time to untangle this
    }
}

我阅读了Difference between @TypeChecked and @CompileStatic 并没有回答这个具体问题。它建议TypeCast允许一些额外的检查,但我不知道它是否默认做额外的检查。

【问题讨论】:

    标签: groovy


    【解决方案1】:

    我会说是的,CompileStatic 意味着 TypeChecked。查看注释接口 TypeCheckedCompileStatic 的 groovy 源代码,我们看到:

    // TypeChecked.java
    @GroovyASTTransformationClass("org.codehaus.groovy.transform.StaticTypesTransformation")
    public @interface TypeChecked {
    

    // CompileStatic.java
    @GroovyASTTransformationClass("org.codehaus.groovy.transform.sc.StaticCompileTransformation")
    public @interface CompileStatic {
    ...
    

    这告诉我们进行实际 AST 转换(注释的工作)的类是 StaticCompileTransformationStaticTypesTransformation

    查看我们得到的代码:

    // Transformation for TypeChecked
    public class StaticTypesTransformation implements ASTTransformation, CompilationUnitAware {
    

    // Transformation for CompileStatic
    public class StaticCompileTransformation extends StaticTypesTransformation {
    

    CompileStatic 的转换扩展了TypeChecked 的转换,因此 CompileStatic 的行为似乎确实是 TypeChecked 行为的超集。

    >

    更深入地挖掘,我们看到转换类使用访问者模式,并且它们分别具有以下方法:

        // StaticTypesTransformation, transformation for TypeChecked
        protected StaticTypeCheckingVisitor newVisitor(SourceUnit unit, ClassNode node) {
            return new StaticTypeCheckingVisitor(unit, node);
        }
    

        // StaticCompileTransformation, transformation for CompileStatic 
        protected StaticTypeCheckingVisitor newVisitor(final SourceUnit unit, final ClassNode node) {
            return new StaticCompilationVisitor(unit, node);
        }
    

    它为每个案例返回一个自定义访问者类。

    看着StaticCompilationVisitor我们看到:

    public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
        ...
        public void visitClass(final ClassNode node) {
            ...
            super.visitClass(node);
            ...
        }
        ...
    }
    

    换句话说,CompileStatic 的访问者类扩展了 TypeChecked 的访问者类,此外,CompileStatic 访问者中的 visitClass 方法(执行实际工作)调用 super.visitClass(node) 其中@ 987654343@ 是 TypeChecked 的访问者类。

    我认为这或多或少地证明了这一点。 CompileStatic 的行为实际上是TypeChecked 行为的超集。

    【讨论】:

    • 非常详尽,谢谢!没看过Groovy源码,挺有意思的。
    • 很高兴它有帮助。如果您觉得这回答了您的问题,请考虑接受答案:stackoverflow.com/help/accepted-answer
    • 对幕后发生的事情进行了很好的分析。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2019-09-23
    相关资源
    最近更新 更多