コンストラクタとアクセッサ

Groovyの場合,引数をつけてコンストラクタを使うと,以下のような動きをする.

  1. 引数なしのコンストラクタを呼ぶ
  2. アクセッサ(setterメソッド)を呼ぶ

アクセッサは自動的に作ってくれるので,以下のようなコンストラクタもアクセッサもないプログラムでもきちんと動く.

//Foo.groovy
class Foo{
  foo
  static void main(args){
    f=new Foo(foo:100) //引数つきのコンストラクタを使う
    println f.foo
  }
}
//end

$ groovy Foo.groovy
100
  

独自のコンストラクタやアクセッサを作っても,動きは同じである.

//Foo.groovy
class Foo{
  foo

  Foo(){ //独自のコンストラクタ
    println "Foo construct!"
  }

  void setFoo(foo){ //独自のアクセッサ
    println "foo set ${foo}"
    this.foo=foo
  }

  static void main(args){
    f=new Foo(foo:100)
    println f.foo
  }
}
//end

$ groovy Foo.groovy
Foo construct!
foo set 100
100
  

引数のあるコンストラクタを作ると,それを優先するので,動きがちょっと違う.自動でアクセッサは呼ばなくなる.

class Foo{
  foo

  Foo(){
    println "Foo construct!"
  }

  Foo(args){ //引数のあるコンストラクタを定義
    println "Foo construct with ${args}!"
  }

  void setFoo(foo){
    println "foo set ${foo}"
    this.foo=foo
  }

  static void main(args){
    f=new Foo(foo:100)
    println f.foo
  }
}

$ groovy Foo.groovy
Foo construct with [foo:100]! ←引数のあるコンストラクタを呼ぶ
null ←アクセッサは呼ばれない
  

引数のあるコンストラクタの中で,明示的にアクセッサを使うと解決する.

class Foo{
  foo

  Foo(){
    println "Foo construct!"
  }

  Foo(args){
    println "Foo construct with ${args}!"
    setFoo args.foo //明示的にアクセッサを呼ぶ
  }

  void setFoo(foo){
    println "foo set ${foo}"
    this.foo=foo
  }

  static void main(args){
    f=new Foo(foo:100)
    println f.foo
  }
}

$ groovy Foo.groovy
Foo construct with [foo:100]!
foo set 100
100
  

なお,動作環境は以下の通りである.

  • Groovy 1.0 beta7
  • JDK 1.4.2_04
  • Windows XP Professional Service Pack1