構造器是我們喜歡重載的一個方法,因為我們在實例化一個類的時候,會遇到各種各樣的情況,比如在某些情況下,一系列類的實例可能有一些相同值的屬性,這時候,我們在實例化對象時,就不希望把這些相同的值分別注入到每一對象中,這樣的工作很繁瑣。
這時候,我們就會重載構造器,但一些時候,比如一些Bean對象,它們的屬性很多,我們就不好在類中重載很多構造器。比如,我們有如下的一個GroovyBean類:
class Reader {
String province
String city
String name
int age
}
這是一個很簡單的GroovyBean類,我們不會在裡面重載構造器了。一般我們都會做如下的實例化:
def reader = new Reader(province:'Guangdong',city:'Shenzhen',name:'Tom',age:22)
現在,我們有這樣一個場景:可能有一批的讀者,都是來自廣東省深圳市,那麼我們把每一個讀者都做上面的初始化,就顯得太繁瑣了。
這時候,我們就可以在運行期內給上面的GroovyBean類重載一個構造器了。如下所示:
Reader.metaClass.constructor = {String name,int age ->
new Reader(province:'Guangdong',city:'Shenzhen',name:name,age:age)
}
在這個構造器裡,我們把屬性"province"和"city"賦給默認值,然後再給構造器注入兩個參數即可。測試代碼如下:
def reader1 = new Reader('Tom',22)
println"""
name: ${reader1.name}
age: ${reader1.age}
address: ${reader1.province} ${reader1.city}"""
def reader2 = new Reader('Mike',20)
println """
name: ${reader2.name}
age: ${reader2.age}
address: ${reader2.province} ${reader2.city}"""
運行結果為:
name: Tom
age: 22
address: Guangdong Shenzhen
name: Mike
age: 20
address: Guangdong Shenzhen
在運行期內我們也可以給類添加一些靜態方法,這裡添加靜態方法有兩種方式,第一種是在運行期內進行攔截。比如我們有如下的一個類:
class Foo {
}
現在這個類裡一個方法也沒有,我們將要在運行期內給它添加一個靜態方法,如下:
Foo.metaClass.'static'.invokeMethod = {
String name,args1 ->
def metaMethod = Foo.metaClass.getStaticMetaMethod(name,args1)
def result
if(metaMethod) result = metaMethod.invoke(name,args1)
else result = 'foo'
result
}
那麼,我們就可以測試它了:
println Foo.foo()
運行結果為:
foo
值得注意的是,下面的代碼行:
def metaMethod = Foo.metaClass.getStaticMetaMethod(name,args1)
是用來獲取指定的靜態方法,如果存在的話,就直接調用,否則就返回"foo"。
如果給上面的Foo類添加一個如下的靜態方法:
def static bar()
{
'bar'
}
再做如下的測試:
println Foo.foo()
println Foo.bar()
則結果為:
foo
bar
這種攔截的方法其實就是在運行期內重載靜態的"invokeMethod"方法。除此之外,我們還可以直接添加靜態方法。
還是上面的Foo類,我們可以使用如下的方法來添加靜態方法:
Foo.metaClass.'static'.hello = {
args1 ->
return "hello,${args1}"
}
這種添加方法就顯得十分的簡單,如果去掉那個"static",就變成了添加一個普通的方法。
現在來做點測試:
println Foo.hello('world')
運行結果為:
hello,world