Ответ 1
Основное отличие: MOP (Meta Object Protocol): @TypeChecked
сохранять методы, проходящие через MOP, а @CompileStatic
генерировать вызовы методов, похожие на байт-код Java. Это означает, что их семантика различна, но это также означает, что вы все еще можете применять метапрограммирование поверх кода @TypeChecked
, если вызов метода может быть разрешен во время компиляции.
Следующий код показывает MOP, действующий на код @TypeChecked
, а не на @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
, поэтому их производительность очень близка., за некоторыми исключениями.
(Обновлено 2016-01-13)
Оба @CompileStatic
и @TypeChecked
позволят:
- Закрытие (включая закрытие делегаций через
@DelegatesTo
); - AST (которые могут использоваться для метапрограммирование времени компиляции);
- Groovy синтаксический сахар, например, в регулярном выражении, списки, карты, перегрузка оператора и т.п.;
- Расширения.
Для @TypeChecked
вы также можете дать указание компилятору игнорировать некоторые проверки типов с помощью Type Checking Extensions, что обеспечивает большую гибкость. @CompileStatic
также поддерживает это, но немного более ограничительный.