@TypeChecked和@CompileStatic之间的区别

时间:2013-11-17 11:21:23

标签: groovy

有人可以解释@TypeChecked和@CompileStatic之间的区别吗?

我用@TypeChecked读到了它,无法在运行时添加新方法。 还有哪些其他功能不允许?

@CompileStatic允许哪些Groovy功能? 与groovyc和@CompileStatic相比,字节码是否与使用javac编译的相同?

2 个答案:

答案 0 :(得分:38)

主要区别在于MOP(元对象协议):@TypeChecked保持方法通过MOP,而@CompileStatic生成类似于Java的字节码的方法调用。这意味着它们的语义不同,但这也意味着您仍然可以在@TypeChecked代码之上应用元编程,只要方法调用可以在编译时解析。

以下代码显示了代理@TypeChecked代码的MOP,而不代表@CompileStatic代码:

import groovy.transform.CompileStatic as CS
import groovy.transform.TypeChecked as TC

class Foo {
  def bar = "bar"
}

class TestTC {
  Foo foo

  TestTC() {
    foo = new Foo()
    foo.metaClass.getBar = { "metaClass'd bar" }
  }

  @TC
  def typed() {
    foo.bar
  }

  @CS 
  def compiled() {
    foo.bar
  }
}

assert new TestTC().typed() == "metaClass'd bar"
assert new TestTC().compiled() == "bar"

对于@CompileStatic,是的,Groovy尝试生成接近javac将输出的字节码,因此their performance are very close,除了少数例外。


(2016-01-13更新)

@CompileStatic@TypeChecked都允许:

  • 闭包(包括通过@DelegatesTo的闭幕授权);
  • ASTs(可用于compile-time metaprogramming);
  • Groovy的合成糖,就像正则表达式,列表,地图,操作符重载等等;
  • Extensions

对于@TypeChecked,您还可以指示编译器通过Type Checking Extensions忽略某些类型检查,从而提供更大的灵活性。 @CompileStatic也支持此功能,但是little more restrictive

答案 1 :(得分:5)

TL / DR;

  • @TypeChecked 只是在编译期间检查类型,但编译后的代码与没有@TypeChecked的行为相同
  • @CompileStatic 检查类似于@TypeChecked,但也会在运行时将代码修改为类型安全,这意味着使用动态编程的方法会中断。