Groovy
![]() Groovyのロゴ | |
パラダイム |
オブジェクト |
---|---|
2003 | |
Java Community Process | |
Guillaume Laforge(プロジェクトマネージャー | |
4.0.21/ 2024 | |
| |
JSR 241 | |
Java、Ruby、Python、Dylan、Smalltalk | |
プラットフォーム | Javaプラットフォーム |
ライセンス | Apache License v2.0 |
ウェブサイト | The Apache Groovy programming language |
groovy |
Groovy(グルービー)は、Javaプラットフォーム
Groovy の
概要
[GroovyはJava
Groovyは
このとき、GroovyコードもJavaコードも、JVMからみると
Groovyは、
言語 仕様
[Groovyの
変数 の型 宣言 は不要 である。通常 の場合 -宣言 をしなかった場合 Object
型 として扱 われ、メソッド呼 び出 しは動的 ディスパッチによって解決 される(変数 の型 の宣言 をすることも可能 であり、静的 なスタイルと動的 なスタイルの場合 に応 じた使 い分 けることができる)。メソッドの引数 や返 り値 の型 宣言 も同様 である。@TypeChecked
を使用 した場合 -変数 の型 を指定 しなかった場合 は型 推論 され、型 が正 しいかどうかチェックされる。メソッド呼 び出 しは動的 ディスパッチのまま。@CompileStatic
を使用 した場合 -上記 に加 えて、メソッド呼 び出 しは静的 に解決 される。@ToString
のようなコンパイル時 のメソッド生成 は通常 通 り使 える。この3種 の中 では最速 。
- メソッド
呼 び出 しの括弧 は省略 できる。 行末 のセミコロンは省略 できる。- リストやマップの
初期 化 を記述 する組 み込 み構文 を持 つ。 演算 子 のオーバーロード定義 (ユーザ定義 演算 子 )が可能 である。組 み込 み型 としてリストやマップを扱 うことができ、それらのリテラル表記 や、それらを処理 する演算 子 が定義 されている。BigDecimal
、BigInteger
型 などについては四則 演算 がオーバーロード定義 されている。
検査 例外 がthrows
宣言 されたメソッドを呼 び出 す際 にも、try
-catch
で囲 んだり、呼 び出 し側 メソッドをthrows
宣言 したりする必要 はない。- プリミティブ
型 は参照 型 と同様 に扱 うことができる(明示 的 な変換 を行 う必要 はない)。 - if
文 やwhile文 、三 項 演算 子 (c?x:y
)の条件 節 では0やnullの値 は偽 として扱 われる(boolean
型 の値 である必要 がない)。 - J2SEの
正規 表現 クラスを扱 うための組 み込 みの演算 子 (=~
や==~
など)が用意 されている。また構文 上 も特別 扱 いされておりPerlやRubyと似 た使用 ができる。 文字 列 定数 中 に任意 のGroovyの式 を埋 め込 むことができる。${}
の記法 を用 いる。これをGStringと呼 ぶ。なお変数 名 の場合 は中 括弧 も不要 であり、"$
の変数 名 "形式 で変数 の値 を文字 列 に埋 め込 むことができる。名前 つき引数 でのメソッド呼 び出 し。- アクセス
修飾 子 のデフォルトはpublic
である。 java.lang
、java.io
、java.math
、java.net
、java.util
、groovy.lang
、groovy.util
は明示 的 に指定 しなくても、暗黙 的 にインポートされている。- groovyファイルで
定義 したクラスはGroovyObject
インタフェースを暗黙 的 に実装 し、クラスの外 で定義 したフィールドやメソッドはScript
抽象 クラスの実装 クラスのフィールドやメソッドとして定義 されたと見 なされる。
クラス定義
[Groovyコードはクラス
println "Hello, World!"
と
class HelloTest {
public HelloTest() {
println "Hello, World!"
}
public static void main(String[] args) {
new HelloTest()
}
}
switch文
[switch
switch (value) {
case "Hello":
println "value == 'Hello'"
break
case String:
println "valueはString型 "
break
case 1..12:
println "valueは1から12の間 "
break
default:
println "それ以外 "
}
forループ
[@CompileStatic
をeach
や times
はクロージャ
for (int i = 0; i < 3; i++) { println "$i: Hello" }
for (i in 1..3) { println "$i: Hello" }
(1..3).each { println "$it: Hello" }
3.times { println "$it: Hello" }
Getter, Setter
[Getter、Setterメソッドは
class Pojo {
def name
}
def pojo = new Pojo(name:"名前 ")
println pojo.getName() // getName()が生成 されている
println pojo.name // getName()が呼 ばれる
デフォルト引数
[デフォルト
def greet(mess = "Hello World") {
println mess
}
greet()
greet("foo")
は
Hello World foo
と
ExpandoMetaClass
[def obj = "foo"
obj.metaClass.greet = { println "Hello World" }
obj.greet()
Expando
[Groovyは
GroovyObject#getProperty(String name)
GroovyObject#setProperty(String name, Object value)
GroovyObject#invokeMethod(String name, Object arguments)
def obj = new Expando()
obj.greetingMessage = "Hello World"
obj.greet = { println greetingMessage }
obj.greet()
obj.message = "foo"
println obj.message
また、this
の
def obj = [:]
obj.greetingMessage = "Hello World"
obj.greet = { println obj.greetingMessage }
obj.greet()
obj.message = "foo"
println obj.message
MOP (Meta Object Protocol)
[GroovyObject#setMetaClass(MetaClass)
class Main {
static void main(String[] array) {
GroovyObject groovyObject = new Main()
Interceptor interceptor = new GreetingInterceptor()
InterceptorUtils.setInterceptor(groovyObject, interceptor)
groovyObject.greet()
}
}
class InterceptorUtils {
static void setInterceptor(GroovyObject groovyObject, Interceptor interceptor) {
ProxyMetaClass proxyMetaClass = ProxyMetaClass.getInstance(groovyObject.getClass())
proxyMetaClass.setInterceptor(interceptor)
groovyObject.setMetaClass(proxyMetaClass)
}
}
class InterceptorImpl implements Interceptor {
Object beforeInvoke(Object groovyExtensionObject, String name, Object[] arguments) {
return null
}
Object afterInvoke(Object groovyExtensionObject, String name, Object[] arguments, Object beforeInvokeReturnObject) {
Object object = invokeMethod(name, arguments)
return object
}
boolean doInvoke() {
return false
}
}
class GreetingInterceptor extends InterceptorImpl {
void greet() {
println "Hello World"
}
}
use
[use
ブロック
import groovy.inspect.Inspector
use (Category.class) {
def obj = "Hoge"
println obj.getShortClassName()
println obj.toString()
}
// 名前 は自由 。
class Category {
// 最初 の引数 は、メソッドが起動 されたインスタンスの参照 コピー。
static getShortClassName(obj) {
Inspector.shortName(obj.getClass())
}
// 実装 メソッドと重複 する場合 、Groovyはカテゴリーより実装 メソッドを優先 。
static String toString(Object obj) {
"Hello World"
}
}
は
String Hoge
と
GroovyMarkup
[Groovyコードの
GroovyMarkupは
GroovyMarkupは
import groovy.xml.MarkupBuilder
class Main {
static void main(array) {
Writer writer = new StringWriter()
writer.println("<?xml version='1.0' ?>")
writer.println()
def builder = new MarkupBuilder(writer)
/*
名前 がルートのタグ名 であるメソッド
引数 がマップである場合 はタグの属性
引数 が文字 列 である場合 はテキストノードの内容 でHTMLエスケープされます。
未 実装 メソッドをハンドルするGroovyObject#invokeMethod(String methodName, Object methodParameter)を利用
メソッドの括弧 が省略 されています。
*/
builder.html(xmlns:"http://www.w3.org/1999/xhtml", "xml:lang":"ja") { //以降 は名前 がタグ名 であるクロージャ
/*
引数 がクロージャである場合 は名前 がタグ名
引数 がマップである場合 はタグの属性
引数 が文字 列 である場合 はテキストノードの内容 でHTMLエスケープされます。
*/
head() {
}
body() {
div("1行 目 ");
div("2行 目 ");
//ヒア・ドキュメント構文
String string = """
<div id='3'>3行 目 </div>
<div id='4'>4行 目 </div>
"""
pre(string) {
}
}
}
println writer.toString()
/*
標準 出力 結果
<?xml version='1.0' ?>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='ja'>
<head />
<body>
<div>1行 目 </div>
<div>2行 目 </div>
<pre>
<div id='3'>3行 目 </div>
<div id='4'>4行 目 </div>
</pre>
</body>
</html>
*/
}
}
クロージャ
[Groovyではコードブロックをファーストクラス(
クロージャは
def str = "Hello World"
def readerClosure = { println str }
readerClosure()
def writerClosure = { str = "foo" }
writerClosure()
println str
このコードを
Hello World foo
と
Groovy JDK
[GroovyからJava SEのFile.eachLine()
といったメソッドを
new File("test.txt").eachLine { println it }
File.eachLine(Closure)
はそれぞれのit
にfinally
java.io.FileInputStream
やjava.io.FileOutputStream
のclose()
Reader.eachLine(Closure)
メソッドなどもFile.getText(String characterCodeSetName)
、Reader.getText()
、Reader.readLines()
というファイルの
他 の言語 からの影響
[James StrachanはGroovyはオブジェクト
適用 分野
[Groovyは
アプリケーションの
Groovyの
標準 化
[Groovyは2004
サンプルコード
[クロージャとループ
[def forLoop() {
def map = [name: "James", location: "London"]
for(e in map) { println "entry $e.key is $e.value" }
}
def closureExample(list) {
list.each { println "value $it" }
}
def values = [1, 2, 3, "abc"]
closureExample(values)
forLoop()
メモ帳
[import groovy.swing.SwingBuilder
import javax.swing.*
def notepad
new SwingBuilder().frame(title: "メモ帳 ", defaultCloseOperation: JFrame.EXIT_ON_CLOSE,
size: [800, 600], show: true, locationRelativeTo: null) {
menuBar() {
menu(text: "ファイル(F)", mnemonic: 'F') {
menuItem(text: "名前 をつけて保存 (A)...", mnemonic: 'A', actionPerformed: {
fc = new JFileChooser()
if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
fc.selectedFile.text = notepad.text
}
})
menuItem(text: "終了 (X)", mnemonic: 'X', actionPerformed: { System.exit(0) })
}
}
scrollPane() { notepad = textArea() }
}
統合 開発 環境
[NetBeans
[NetBeansは
構文 の強調 表示 、コード折 り畳 み、およびコード補完 をサポート。
Eclipse
[EclipseはプラグインにてGroovyをサポートしている[6]。
変数 の型 を指定 したものは、メソッドの補完 が可能 。- リファクタリング。メソッドの
抽出 、名前 の変更 など。 - デバッガ
- ソースコードの
整形 。
IntelliJ IDEA
[IntelliJ IDEA では Groovy や Grails や Gant などが
補完 ができる。- JavaとGroovyが
相互 に補完 ができ、JavaのクラスをGroovyで補完 できるだけでなく、リアルタイムでGroovyのクラスをJavaで補完 が可能 。JavaとGroovyをプロジェクト内 に混在 させることができる。
- JavaとGroovyが
- Ctrl + クリックによる、
定義 した場所 への移動 。補完 同様 、JavaとGroovy相互 の移動 が可能 。
- Dynamic properties により、
動的 に追加 されるメンバ変数 を管理 することができる。これにより、動的 に追加 されるメンバ変数 に対 しても補完 やスペルミスのチェックが可能 になる。 - デバッガ
- コーディング
上 のエラーに対 して、リアルタイムで表示 し、Quick-fix ができる。 - GroovyDoc に
対 しても補完 が使 える。 名前 の変更 やメソッドの抽出 や変数 の導入 などのリファクタリング機能 がある。- Groovyでの
名前 の変更 は、同時 にJavaのソースコードに対 しても修正 (リファクタリング)がかかる。
- Groovyでの
- Grails や Groovy Server Pages (GSP) をサポートしている。
- Gant や Apache Ivy をサポートしていて、Gant に
対 して補完 やデバッガによるデバッグができる。 - Gradle を Gradle GUI Plugin でサポート。
参照
[- ^ “Tags · apache/groovy · GitHub”. 2024
年 6月 23日 閲覧 。 - ^ The Apache Groovy programming language - Download
- ^ Groovy Projects intends to join the Apache Software Foundation -- Guillaume Laforge's Blog
- ^ The Apache Groovy programming language - Semantics - §switch / case
- ^ JSR 241: The Groovy Programming Language
- ^ Groovy Development Tools | Eclipse Plugins, Bundles and Products - Eclipse Marketplace | Eclipse Foundation
- ^ IntelliJ IDEA :: Smart Groovy IDE with Groovy-Java compiler for Groovy scripts, Groovy Swingbuilder, Groovy server pages with ER diagram for productive Groovy programming, plus Groovy on Grails, available via Groovy plugin