2011-09-14 93 views
4

Groovy支持默認參數和命名參數。我只是沒有看到他們一起工作。Groovy命名和默認參數

我需要一些類使用命名參數簡單的非,並使用類似下面命名的參數,以支持建設:

def a1 = new A(2) 
def a2 = new A(a: 200, b: "non default") 

class A extends SomeBase { 
    def props 
    A(a=1, b="str") { 
     _init(a, b) 
    } 

    A(args) { 
     // use the values in the args map: 
     _init(args.a, args.b) 
     props = args 
    } 

    private _init(a, b) { 
    } 

} 

是它總體上是好的做法,同時支持?上面的代碼是唯一的方法嗎?

回答

6

給定的代碼會導致一些問題。特別是,它將生成兩個帶有單個Object參數的構造函數。第一個構造函數生成的字節代碼等同於:

A() // a,b both default 
A(Object) // a set, b default 
A(Object, Object) // pass in both 

第二生成此:

A(Object) // accepts any object 

您可以通過添加某些類型的解決這個問題。儘管groovy具有動態類型,但方法和構造函數中的類型聲明仍然很重要。例如:

A(int a = 1, String b = "str") { ... } 
A(Map args) { ... } 

至於好的做法,我會簡單地使用groovy.transform.Canonicalgroovy.transform.TupleConstructor註解之一。他們將自動提供正確的屬性圖和位置參數構造函數。 TupleConstructor僅提供構造函數,Canonical適用於關於equals,hashCodetoString的其他一些最佳實踐。