浑身疼吃什么药管用| 子宫肌瘤有什么症状表现| 查甲状腺挂什么科| 眼镜轴位是什么| cupid什么意思| 高血脂吃什么药| 梦见自己抬棺材是什么意思| 性是什么| 立冬吃什么东西| 吃香蕉有什么好处| 猫的偏旁叫什么| 华西医院院长什么级别| 6月16什么星座| 1946年属什么生肖| 腰椎退行性变什么意思| 臭嗨是什么意思| 海豹吃什么| 备孕需要做些什么准备| 奶奶的妈妈叫什么| 孕妇喝可乐对胎儿有什么影响| 小猫泪痕重什么原因| 吃什么药能减肥| 一马平川是什么意思| 身上长红点很痒是什么原因| 检验葡萄糖用什么试剂| 脱髓鞘疾病是什么病| 甘露丸是什么| 新生儿囟门什么时候闭合| 6月份出生是什么星座| 1月29日什么星座| 118是什么星座| 五花大绑是什么意思| 牛鞭是什么东西| 消化不良反酸吃什么药| 低血压和低血糖有什么区别| cho是什么意思| lv中文名叫什么| 什么是大运| 马齿苋有什么功效| 欲情故纵什么意思| 肚子拉稀是什么原因| 紫菜吃多了有什么坏处| 消化不好吃什么药最好| 纵欲是什么意思| 万事达卡是什么卡| 办理护照需要什么手续| 中二病是什么意思| 1990属马佩戴什么最佳| 吃什么降三高最快| 黑科技是什么| 泌乳素是什么| 尖牙什么时候换| 不睡人的空床放点什么| 身上老出汗是什么原因引起的| 18k金是什么材质| 幻听是什么症状| 胸腔积液叩诊什么音| 由可以组什么词| 九月份什么星座| 热退疹出是什么病| 人参补什么| 双手麻是什么原因| 一六年属什么生肖| 大脸适合什么发型| 什么的日子| 脸上长痘是什么原因| 化学阉割什么意思| 什么牌子的山地车好骑又不贵| 椎间盘膨出是什么意思| 高兴的什么| 子宫有积液是什么原因引起的| 白果治什么病| 吃什么营养神经| 厅局级是什么级别| 人缺钾有什么症状| 牙疼吃什么消炎药最好| 绞股蓝长什么样| 藏青色是什么颜色| 什么是地包天牙齿图片| 土地出让金是什么意思| 吃什么容易排便| 怀孕什么时候可以同房| 用什么擦地最干净| 食品科学与工程学什么| 生蚝和牡蛎有什么区别| 刘邦是什么星座| 农历十月十八是什么星座| 什么是丹毒| 舌苔黄腻吃什么中成药| 蛇怕什么东西| 新生儿拉稀是什么原因| 二尖瓣微量反流什么意思| 乳液是什么| l是什么字| gbm是什么意思| 梦见吃水饺是什么预兆| 什么季节减肥效果最快最好| 9月13日是什么星座| 兔子的尾巴像什么| 美人坯子是什么意思| 两眼中间的位置叫什么| 瑾字属于五行属什么| sanag是什么牌子| adivon是什么牌子| 20属什么生肖| 65什么意思| 卵子排出体外是什么样子| 龙骨是什么东西| pr是什么意思医学| 椎间盘轻度膨出是什么意思| 子宫癌筛查做什么检查| 高温天气喝什么茶解暑| 妈妈的妹妹叫什么| dha有什么作用| 纾字五行属什么| 藤茶是什么茶| 火象是什么星座| 杜甫是什么朝代的| 绣眼鸟吃什么| 未亡人什么意思| 多西他赛是什么药| 麻辣拌里面都有什么菜| 胃食管反流病是什么原因造成的| 桃花是指什么生肖| 智齿疼吃什么药| 邵字五行属什么| 狗肚子有虫子吃什么药| 火药是什么时候发明的| jewelry什么意思| 一家之主是什么意思| 左脸长痣代表什么| 经常拉肚子吃什么药好| 提心吊胆是什么意思| 胡萝卜不能和什么食物一起吃| 花呗是什么意思| bv是什么| 氯雷他定什么时候吃| 减肥吃什么| 黑绿色大便是什么原因| 头发长得慢是什么原因| 阑尾炎什么症状表现| 尿沉渣检查什么| 狗狗喝什么水| 6月12日什么星座| 苦瓜什么人不能吃| 非淋菌性尿道炎吃什么药最好| 2014年什么年| 第57个民族是什么民族| 抗心磷脂抗体是什么| 肠梗阻是什么症状| 行气是什么意思| 10月27是什么星座| 胚胎和囊胚有什么区别| 愚人节是什么意思| 打破伤风挂什么科| 宫颈欠光滑是什么意思| 三十六计的第一计是什么| 老年阴道炎用什么药| 什么的季节| 外科和内科有什么区别| 吃糖醋蒜有什么好处和坏处| 什么是赤道| 帅是什么意思| 体脂是什么| 什么是面瘫| 美国绿卡有什么好处| 核桃什么时候吃最好| 咳嗽喉咙痒吃什么药| 什么的辨认| 过期的咖啡有什么用途| 行尸走肉是什么意思| 有酒窝的女人代表什么| 怀孕做糖耐是检查什么| 排斥一个人什么意思| 姨妈期吃什么水果| 乱花渐欲迷人眼是什么意思| 什么泡水喝杀幽门螺杆菌| 爽肤水和精华水有什么区别| 甲亢都有什么症状| 子宫内膜c型什么意思| 什么如什么| 皮蛋和什么不能一起吃| 放疗后吃什么恢复快| 开天门是什么意思| 狸是什么动物| 日本旅游买什么东西最划算| b类火灾是指什么| 为什么会得口腔溃疡| 狗狗不能吃什么| 脚心痒是什么预兆| 心脏不舒服挂什么科室| pci是什么| 九月什么星座| 复印病历需要什么证件| 吃醪糟有什么好处| 什么是爬虫| 灌肤是什么意思| 黄山四绝是什么| 嗓子痒干咳是什么原因| 蚊子怕什么味道| 荣辱与共是什么生肖| 脂肪肝是什么引起的| 头尖适合什么发型| epa是什么意思| 黄体囊肿是什么意思| gm是什么| 尿酸高看什么科| 无偿献血证有什么用| 补办身份证需要带什么| 原发性和继发性是什么意思| 凤梨和菠萝有什么区别| 任督二脉是什么意思| 附属国是什么意思| 梦见离家出走是什么意思| 小t是什么意思| 来大姨妈拉肚子是什么原因| 梦到被蜜蜂蛰是什么意思| 阳亢是什么意思| 胆结石是什么| 王晶老婆叫什么名字| 不到长城非好汉的下一句是什么| 骨钙素低是什么原因| 血糖高吃什么水果降糖| 做梦遗精是什么原因| 釉面是什么意思| 疏风解表的意思是什么| 今晚开什么特马| 侵犯是什么意思| 什么情况下吃奥司他韦| 12月17日什么星座| 肝最怕什么| 每天吃什么菜谱星期表| 如饥似渴是什么意思| c14和c13有什么区别| clot什么牌子| nt是什么币| 氧化剂是什么| 节育环嵌顿是什么意思| 冠心病吃什么药最有效| 甲状腺肿是什么意思| 烘焙是什么意思| 什么人不能吃秋葵| 限购是什么意思| 女人细菌感染什么原因引起的| 血糖高有什么表现| 乙肝弱阳性是什么意思| 单飞什么意思| 酸奶可以做什么美食| 72年鼠是什么命| 冰箱底部漏水是什么原因| nbr是什么材质| 勃起困难吃什么药| 二甲双胍是什么药| 橄榄菜长什么样子图片| 篮子房是什么意思| 浅表性胃炎吃什么中药| 木薯是什么| 舌苔厚黄吃什么药| 腿抽筋挂什么科| 补锌吃什么| 什么是积食| 蚊子怕什么颜色| 试管是什么| 氨咖黄敏胶囊是什么药| 百度Jump to content

Documentación en Xinhua

From Wikipedia, the free encyclopedia
Groovy
Groovy Logo
ParadigmMulti-paradigm: object-oriented, imperative, functional, aspect-oriented, scripting
Designed byJames Strachan
DeveloperPaul King (PMC Chair)
Jochen Theodorou (Tech Lead)
Guillaume Laforge
Cedric Champeau
Daniel Sun
Eric Milles
First appeared2003; 22 years ago (2003)
Stable release4.0.27[1] Edit this on Wikidata (24 May 2025; 2 months ago (24 May 2025)) [±]
Typing disciplineDynamic, static, strong, duck
PlatformJava SE
LicenseApache License 2.0
Filename extensions.groovy, .gvy, .gy, .gsh[2]
Websitegroovy-lang.org Edit this at Wikidata
Major implementations
Gradle, Grails
Influenced by
Java, Python, Ruby, Smalltalk, Perl
Influenced
Kotlin
百度 现场鸦雀无声,一时间所有人都愣住了。

Apache Groovy is a Java-syntax-compatible object-oriented programming language for the Java platform. It is both a static and dynamic language with features similar to those of Python, Ruby, and Smalltalk. It can be used as both a programming language and a scripting language for the Java Platform, is compiled to Java virtual machine (JVM) bytecode, and interoperates seamlessly with other Java code and libraries. Groovy uses a curly-bracket syntax similar to Java's. Groovy supports closures, multiline strings, and expressions embedded in strings. Much of Groovy's power lies in its AST transformations, triggered through annotations.

Groovy 1.0 was released on January 2, 2007, and Groovy 2.0 in July, 2012. Since version 2, Groovy can be compiled statically, offering type inference and performance near that of Java.[3][4] Groovy 2.4 was the last major release under Pivotal Software's sponsorship which ended in March 2015.[5] Groovy has since changed its governance structure to a Project Management Committee in the Apache Software Foundation.[6]

History

[edit]

James Strachan first talked about the development of Groovy on his blog in August 2003.[7] In March 2004, Groovy was submitted to the Java Community Process (JCP) as JSR 241[8] and accepted by ballot. Several versions were released between 2004 and 2006. After the JCP standardization effort began, the version numbering changed, and a version called "1.0" was released on January 2, 2007. After various betas and release candidates numbered 1.1, on December 7, 2007, Groovy 1.1 Final was released and immediately renumbered as Groovy 1.5 to reflect the many changes made.

In 2007, Groovy won the first prize at JAX 2007 innovation award.[9] In 2008, Grails, a Groovy web framework, won the second prize at JAX 2008 innovation award.[10]

In November 2008, SpringSource acquired the Groovy and Grails company (G2One).[11] In August 2009 VMware acquired SpringSource.[12]

In April 2012, after eight years of inactivity, the Spec Lead changed the status of JSR 241 to dormant.[8]

Strachan had left the project silently a year before the Groovy 1.0 release in 2007.[citation needed] In Oct 2016, Strachan stated "I still love groovy (jenkins pipelines are so groovy!), java, go, typescript and kotlin".[13]

On July 2, 2012, Groovy 2.0 was released, which, among other new features, added static compiling and static type checking.

When the Pivotal Software joint venture was spun-off by EMC Corporation (EMC) and VMware in April 2013, Groovy and Grails formed part of its product portfolio. Pivotal ceased sponsoring Groovy and Grails from April 2015.[5] That same month, Groovy changed its governance structure from a Codehaus repository to a Project Management Committee (PMC) in the Apache Software Foundation via its incubator.[6] Groovy graduated from Apache's incubator and became a top-level project in November 2015.[14]

On February 7, 2020, Groovy 3.0 was released.[15] Version 4.0 was released on January 25, 2022.[16]

Features

[edit]

Most valid Java files are also valid Groovy files. Although the two languages are similar, Groovy code can be more compact, because it does not need all the elements that Java needs.[17] This makes it possible for Java programmers to learn Groovy gradually by starting with familiar Java syntax before acquiring more Groovy programming idioms.[18]

Groovy features not available in Java include both static and dynamic typing (with the keyword def), operator overloading, native syntax for lists and associative arrays (maps), native support for regular expressions, polymorphic iteration, string interpolation, added helper methods, and the safe navigation operator ?. to check automatically for null pointers (for example, variable?.method(), or variable?.field).[19]

Since version 2, Groovy also supports modularity (shipping only the jars that the project uses, thus reducing the size of Groovy's library), type checking, static compilation, Project Coin syntax enhancements, multicatch blocks and ongoing performance enhancements using the invokedynamic instruction introduced in Java 7.[20]

Groovy natively supports markup languages such as XML and HTML by using an inline Document Object Model (DOM) syntax. This feature enables the definition and manipulation of many types of heterogeneous data assets with a uniform and concise syntax and programming methodology.[citation needed]

Unlike Java, a Groovy source code file can be executed as an (uncompiled) script, if it contains code outside any class definition, if it is a class with a main method, or if it is a Runnable or GroovyTestCase. A Groovy script is fully parsed, compiled, and generated before executing (similar to Python and Ruby). This occurs under the hood, and the compiled version is not saved as an artifact of the process.[21]

GroovyBeans, properties

[edit]

GroovyBeans are Groovy's version of JavaBeans. Groovy implicitly generates getters and setters. In the following code, setColor(String color) and getColor() are implicitly generated. The last two lines, which appear to access color directly, are actually calling the implicitly generated methods.[22]

class AGroovyBean {
  String color
}

def myGroovyBean = new AGroovyBean()

myGroovyBean.setColor('baby blue')
assert myGroovyBean.getColor() == 'baby blue'

myGroovyBean.color = 'pewter'
assert myGroovyBean.color == 'pewter'

Groovy offers simple, consistent syntax for handling lists and maps, reminiscent of Java's array syntax.[23]

def movieList = ['Dersu Uzala', 'Ran', 'Seven Samurai']  // Looks like an array, but is a list
assert movieList[2] == 'Seven Samurai'
movieList[3] = 'Casablanca'  // Adds an element to the list
assert movieList.size() == 4

def monthMap = [ 'January' : 31, 'February' : 28, 'March' : 31 ]  // Declares a map
assert monthMap['March'] == 31  // Accesses an entry
monthMap['April'] = 30  // Adds an entry to the map
assert monthMap.size() == 4

Prototype extension

[edit]

Groovy offers support for prototype extension through ExpandoMetaClass, Extension Modules (only in Groovy 2), Objective-C-like Categories and DelegatingMetaClass.[24]

ExpandoMetaClass offers a domain-specific language (DSL) to express the changes in the class easily, similar to Ruby's open class concept:

Number.metaClass {
  sqrt = { Math.sqrt(delegate) }
}

assert 9.sqrt() == 3
assert 4.sqrt() == 2

Groovy's changes in code through prototyping are not visible in Java, since each attribute/method invocation in Groovy goes through the metaclass registry. The changed code can only be accessed from Java by going to the metaclass registry.

Groovy also allows overriding methods as getProperty(), propertyMissing() among others, enabling the developer to intercept calls to an object and specify an action for them, in a simplified aspect-oriented way. The following code enables the class java.lang.String to respond to the hex property:

enum Color {
  BLACK('#000000'), WHITE('#FFFFFF'), RED('#FF0000'), BLUE('#0000FF')
  String hex
  Color(String hex) { 
    this.hex = hex 
  }
}

String.metaClass.getProperty = { String property ->
  def stringColor = delegate
  if (property == 'hex') {
    Color.values().find { it.name().equalsIgnoreCase stringColor }?.hex
  }
}

assert "WHITE".hex == "#FFFFFF"
assert "BLUE".hex == "#0000FF"
assert "BLACK".hex == "#000000"
assert "GREEN".hex == null

The Grails framework uses metaprogramming extensively to enable GORM dynamic finders, like User.findByName('Josh') and others.[25]

Dot and parentheses

[edit]

Groovy's syntax permits omitting parentheses and dots in some situations. The following groovy code

take(coffee).with(sugar, milk).and(liquor)

can be written as

take coffee with sugar, milk and liquor

enabling the development of domain-specific languages (DSLs) that look like plain English.

Functional programming

[edit]

Although Groovy is mostly an object-oriented language, it also offers functional programming features.

Closures

[edit]

According to Groovy's documentation: "Closures in Groovy work similar to a 'method pointer', enabling code to be written and run in a later point in time".[26] Groovy's closures support free variables, i.e. variables that have not been explicitly passed as a parameter to it, but exist in its declaration context, partial application (that it terms 'currying'[27]), delegation, implicit, typed and untyped parameters.

When working on Collections of a determined type, the closure passed to an operation on the collection can be inferred:

list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* 
 * Non-zero numbers are coerced to true, so when it % 2 == 0 (even), it is false.
 * The type of the implicit "it" parameter can be inferred as an Integer by the IDE.
 * It could also be written as:
 * list.findAll { Integer i -> i % 2 }
 * list.findAll { i -> i % 2 }
 */
def odds = list.findAll { it % 2 }

assert odds == [1, 3, 5, 7, 9]

A group of expressions can be written in a closure block without reference to an implementation and the responding object can be assigned at a later point using delegation:

// This block of code contains expressions without reference to an implementation
def operations = {
  declare 5
  sum 4
  divide 3
  print
}
/* 
 * This class will handle the operations that can be used in the closure above. Another class
 * could be declared having the same methods, but using, for example, webservice operations
 * in the calculations.
 */
class Expression {
  BigDecimal value

  /* 
   * Though an Integer is passed as a parameter, it is coerced into a BigDecimal, as was 
   * defined. If the class had a 'declare(Integer value)' method, it would be used instead.
   */
  def declare(BigDecimal value) {
    this.value = value
  }
  
  def sum(BigDecimal valueToAdd) {
    this.value += valueToAdd
  }
  
  def divide(BigDecimal divisor) {
    this.value /= divisor
  }
  
  def propertyMissing(String property) {
    if (property == "print") println value
  }
}
// Here is defined who is going to respond the expressions in the block of code above.
operations.delegate = new Expression()
operations()

Curry

[edit]

Usually called partial application,[27] this Groovy feature allows closures' parameters to be set to a default parameter in any of their arguments, creating a new closure with the bound value. Supplying one argument to the curry() method will fix argument one. Supplying N arguments will fix arguments 1 .. N.

def joinTwoWordsWithSymbol = { symbol, first, second -> first + symbol + second }
assert joinTwoWordsWithSymbol('#', 'Hello', 'World') == 'Hello#World'

def concatWords = joinTwoWordsWithSymbol.curry(' ')
assert concatWords('Hello', 'World') == 'Hello World'

def prependHello = concatWords.curry('Hello')
//def prependHello = joinTwoWordsWithSymbol.curry(' ', 'Hello')
assert prependHello('World') == 'Hello World'

Curry can also be used in the reverse direction (fixing the last N arguments) using rcurry().

def power = { BigDecimal value, BigDecimal power ->
  value**power
}

def square = power.rcurry(2)
def cube = power.rcurry(3)

assert power(2, 2) == 4
assert square(4) == 16
assert cube(3) == 27

Groovy also supports lazy evaluation,[28][29] reduce/fold,[30] infinite structures and immutability,[31] among others.[32]

JSON and XML processing

[edit]

On JavaScript Object Notation (JSON) and XML processing, Groovy employs the Builder pattern, making the production of the data structure less verbose. For example, the following XML:

<languages>
  <language year="1995">
    <name>Java</name>
    <paradigm>object oriented</paradigm>
    <typing>static</typing>
  </language>
  <language year="1995">
    <name>Ruby</name>
    <paradigm>functional, object oriented</paradigm>
    <typing>duck typing, dynamic</typing>
  </language>
  <language year="2003">
    <name>Groovy</name>
    <paradigm>functional, object oriented</paradigm>
    <typing>duck typing, dynamic, static</typing>
  </language>
</languages>

can be generated via the following Groovy code:

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.languages {
  language(year: 1995) {
    name "Java"
    paradigm "object oriented"
    typing "static"
  }
  language (year: 1995) {
    name "Ruby"
    paradigm "functional, object oriented"
    typing "duck typing, dynamic"
  }
  language (year: 2003) {
    name "Groovy"
    paradigm "functional, object oriented"
    typing "duck typing, dynamic, static"
  }
}

and also can be processed in a streaming way through StreamingMarkupBuilder. To change the implementation to JSON, the MarkupBuilder can be swapped to JsonBuilder.[33]

To parse it and search for a functional language, Groovy's findAll method can serve:

def languages = new XmlSlurper().parseText writer.toString()

// Here is employed Groovy's regex syntax for a matcher (=~) that will be coerced to a 
// boolean value: either true, if the value contains our string, or false otherwise.
def functional = languages.language.findAll { it.paradigm =~ "functional" }
assert functional.collect { it.name } == ["Groovy", "Ruby"]

String interpolation

[edit]

In Groovy, strings can be interpolated with variables and expressions by using GStrings:[34]

BigDecimal account = 10.0
def text = "The account shows currently a balance of $account"
assert text == "The account shows currently a balance of 10.0"

GStrings containing variables and expressions must be declared using double quotes.

A complex expression must be enclosed in curly brackets. This prevents parts of it from being interpreted as belonging to the surrounding string instead of to the expression:

BigDecimal minus = 4.0
text = "The account shows currently a balance of ${account - minus}"
assert text == "The account shows currently a balance of 6.0"

// Without the brackets to isolate the expression, this would result:
text = "The account shows currently a balance of $account - minus"
assert text == "The account shows currently a balance of 10.0 - minus"

Expression evaluation can be deferred by employing arrow syntax:

BigDecimal tax = 0.15
text = "The account shows currently a balance of ${->account - account*tax}"
tax = 0.10

// The tax value was changed AFTER declaration of the GString. The expression 
// variables are bound only when the expression must actually be evaluated:
assert text == "The account shows currently a balance of 9.000"

Abstract syntax tree transformation

[edit]

According to Groovy's own documentation, "When the Groovy compiler compiles Groovy scripts and classes, at some point in the process, the source code will end up being represented in memory in the form of a Concrete Syntax Tree, then transformed into an Abstract Syntax Tree. The purpose of AST Transformations is to let developers hook into the compilation process to be able to modify the AST before it is turned into bytecode that will be run by the JVM. AST Transformations provides Groovy with improved compile-time metaprogramming capabilities allowing powerful flexibility at the language level, without a runtime performance penalty."[35]

Examples of ASTs in Groovy are:

  • Category and Mixin transformation
  • Immutable AST Macro
  • Newify transformation
  • Singleton transformation

among others.

The testing framework Spock uses AST transformations to allow the programmer to write tests in a syntax not supported by Groovy, but the relevant code is then manipulated in the AST to valid code.[36] An example of such a test is:

def "maximum of #a and #b is #c" () {
  expect:
  Math.max (a, b) == c

  where:
  a | b || c
  3 | 5 || 5
  7 | 0 || 7
  0 | 0 || 0
}

Traits

[edit]

According to Groovy's documentation, "Traits are a structural construct of the language that allows: composition of behaviors, runtime implementation of interfaces, behavior overriding, and compatibility with static type checking/compilation."

Traits can be seen as interfaces carrying both default implementations and state. A trait is defined using the trait keyword:

trait FlyingAbility { /* declaration of a trait */
  String fly() { "I'm flying!" } /* declaration of a method inside a trait */
}

Then, it can be used like a normal interface using the keyword implements:

class Bird implements FlyingAbility {} /* Adds the trait FlyingAbility to the Bird class capabilities */
def bird = new Bird() /* instantiate a new Bird */
assert bird.fly() == "I'm flying!" /* the Bird class automatically gets the behavior of the FlyingAbility trait */

Traits allow a wide range of abilities, from simple composition to testing.

Adoption

[edit]

Notable examples of Groovy adoption include:

IDE support

[edit]

Many integrated development environments (IDEs) and text editors support Groovy:

Dialects

[edit]

There is one alternative implementation of Groovy:

  • Grooscript converts Groovy code to JavaScript code.[46] Although Grooscript has some limitations compared to Apache Groovy, it can use domain classes in both the server and the client.[47] Plugin support for Grails version 3.0 is provided, as well as online code conversions.[48]

See also

[edit]

References

[edit]

Citations

[edit]
  1. ^ "Release 4.0.27". 24 May 2025. Retrieved 25 May 2025.
  2. ^ "Groovy Goodness: Default Groovy Script File Extensions".
  3. ^ "Groovy 2.0 Performance compared to Java". 25 Aug 2012.
  4. ^ "Java vs Groovy2.0 vs Scala Simple Performance Test". 10 Jul 2012. Archived from the original on 10 December 2012. Retrieved 7 October 2012.
  5. ^ a b "Groovy 2.4 And Grails 3.0 To Be Last Major Releases Under Pivotal Sponsorship". 19 Jan 2015.
  6. ^ a b "Groovy joins Apache Incubator". 11 Mar 2015.
  7. ^ James Strachan (29 Aug 2003). "Groovy - the birth of a new dynamic language for the Java platform". Archived from the original on 1 September 2003.
  8. ^ a b "Java Community Process JSR 241".
  9. ^ "Groovy wins first prize at JAX 2007 innovation award". 2025-08-06. Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  10. ^ "They say a lot can happen over a cup of coffee". Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  11. ^ "SpringSource Acquires Groovy and Grails company (G2One)". 11 Nov 2008.
  12. ^ "VMWare Acquires SpringSource". 10 Aug 2009.
  13. ^ "Tweet from James Strachan". November 24, 2016. Retrieved 2025-08-06.
  14. ^ "Announcement on dev mailing list".
  15. ^ "Release GROOVY_3_0_0 · apache/groovy". GitHub. Retrieved 2025-08-06.
  16. ^ "Release GROOVY_4_0_0 · apache/groovy". GitHub. Retrieved 2025-08-06.
  17. ^ K?nig 2007, pg. 32
  18. ^ "Groovy style and language feature guidelines for Java developers". Groovy.codehaus.org. Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  19. ^ "Groovy – Differences from Java". Groovy.codehaus.org. Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  20. ^ "What's new in Groovy 2.0?". 28 Jun 2012.
  21. ^ K?nig 2007, pp. 37-8
  22. ^ K?nig 2007, pp. 38-9
  23. ^ K?nig 2007, pp. 41-3
  24. ^ "JN3525-MetaClasses". Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  25. ^ "Metaprogramming Techniques in Groovy and Grails". 11 Jun 2009.
  26. ^ "Groovy - Closures". Archived from the original on 2025-08-06.
  27. ^ a b "Does groovy call partial application 'currying'", 10 Aug 2013
  28. ^ "Groovy - Lazy Transformation". Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  29. ^ "Side Notes: Lazy lists in Groovy". 3 Feb 2011.
  30. ^ "Groovy's Fold". 20 Jun 2011. Archived from the original on 13 February 2015. Retrieved 12 February 2015.
  31. ^ "Functional Programming with Groovy". 5 Nov 2011.
  32. ^ "Function programming in Groovy". Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  33. ^ "JsonBuilder". Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  34. ^ "Groovy Strings - Different ways of creating them". 26 Dec 2009.
  35. ^ "Compile-time Metaprogramming - AST Transformations". Archived from the original on 2025-08-06. Retrieved 2025-08-06.
  36. ^ King, Paul (2020). "A History of the Groovy Programming Language". Proc. ACM Program. Lang. 4: 53. doi:10.1145/3386326.
  37. ^ "Groovy DSL for OFBiz business logic". Apache OFBiz Project Open Wiki.
  38. ^ "Simple-methods examples using Groovy". Apache OFBiz Project Open Wiki.
  39. ^ "Grails at LinkedIn". Retrieved 2025-08-06.
  40. ^ "Jenkins Pipeline".
  41. ^ Rocher, Graeme (October 2, 2008). "Graeme Rocher's Blog: Sky.com relaunches written in Grails". Graeme Rocher's Blog. Retrieved 2025-08-06.
  42. ^ Security Analysis of Emerging Smart Home Applications
  43. ^ "Scripting and the Script Library | Scripting & Properties". www.soapui.org. Retrieved 2025-08-06.
  44. ^ "Wired.Com" (PDF). www.springsource.org. Retrieved 2025-08-06.
  45. ^ "XWiki SAS" (PDF). www.springsource.org. Retrieved 2025-08-06.
  46. ^ "Grooscript Documentation". 12 Sep 2016. Archived from the original on 28 June 2017. Retrieved 4 July 2017.
  47. ^ "Presentation at SpringOne/2GX on Grooscript". 13 Dec 2015.
  48. ^ "Grooscript online conversions". 15 May 2017. Archived from the original on 9 July 2017. Retrieved 4 July 2017.

Sources

[edit]
[edit]
头晕眼花吃什么药 什么是三界五行 loft是什么意思 时迁的绰号是什么 吃黄体酮有什么副作用
四海是什么意思 男人壮阳吃什么最快 梦见男朋友出轨了是什么意思 脑出血什么原因引起的 艾灸痒痒的是什么原因
右眼一直跳什么情况 总是心慌是什么原因 晚上饿了吃什么不长胖 吃什么药升血小板最快 为什么我不快乐
茅根是什么 梦见迁祖坟有什么预兆 四九城是什么意思 一片冰心在玉壶的冰心是什么意思 蝴蝶是什么变的
岁寒三友指什么jasonfriends.com 冷宫是什么意思hcv8jop3ns1r.cn 子宫内膜为什么会增厚hcv8jop5ns0r.cn 质数是什么hcv9jop1ns1r.cn 者加羽念什么hcv9jop4ns0r.cn
王妃是什么意思hcv8jop3ns6r.cn 十月份什么星座hcv7jop7ns3r.cn 胖大海配什么喝治咽炎hcv9jop5ns2r.cn 孕妇喝纯牛奶对胎儿有什么好处hcv9jop2ns0r.cn 口水臭吃什么药hcv9jop3ns3r.cn
蛇缠腰是什么病hcv7jop4ns6r.cn 重字五行属什么hcv8jop1ns8r.cn 小孩肠胃感冒吃什么药比较好hcv8jop9ns1r.cn 脱发补充什么维生素hcv8jop4ns0r.cn 檀郎是什么意思hcv9jop1ns7r.cn
女性检查甲功是什么病hcv8jop3ns6r.cn 花胶适合什么人吃creativexi.com 转氨酶高是什么情况hcv8jop4ns5r.cn 为什么会脑供血不足hcv8jop1ns0r.cn 跳蚤喜欢咬什么样的人hcv9jop6ns1r.cn
百度