2014-10-14 9 views
10

खोने के बिना कस्टम कन्स्ट्रक्टर जोड़ना डिफ़ॉल्ट रूप से प्रत्येक ग्रोवी क्लास में नक्शा कन्स्ट्रक्टर होता है, उदा।डिफॉल्ट मैप कन्स्ट्रक्टर

class Foo { 
    def a 
    def b 
} 

// this works 
new Foo(a: '1', b: '2') 

हालांकि, यह डिफ़ॉल्ट नक्शा खोने के बिना अपने स्वयं के निर्माता को जोड़ने के लिए लगता है कि जैसे ही आप अपनी खुद की एक निर्माता के रूप में जोड़ने, यह डिफ़ॉल्ट निर्माता उपलब्ध

class Foo { 

    Foo(Integer x) { 
    println 'my constructor was called' 
    } 

    def a 
    def b 
} 

// this works 
new Foo(1) 

// now this doesn't work, I get the error: groovy.lang.GroovyRuntimeException: 
// failed to invoke constructor 
new Foo(a: '1', b: '2') 

नहीं है, यह संभव है निर्माता? मैंने कक्षा को @TupleConstructor के साथ एनोटेट करने का प्रयास किया लेकिन इससे कोई फर्क नहीं पड़ता। मुझे एहसास है कि मैं नक्शा कन्स्ट्रक्टर स्वयं जोड़ सकता हूं, उदा।

public Foo(Map map) {  
    map?.each { k, v -> this[k] = v } 
} 

हालांकि निर्माता ऊपर डिफ़ॉल्ट नक्शा निर्माता के समान नहीं है, क्योंकि मानचित्र में एक महत्वपूर्ण है कि कक्षा में एक इसी संपत्ति नहीं है एक अपवाद का कारण होगा।

उत्तर

18

आप @InheritConstructors एनोटेशन का उपयोग कर सकते हैं।

@groovy.transform.InheritConstructors 
class Foo { 
    def a, b 
    Foo(Integer x) { 
     println 'my constructor was called' 
    } 
} 

// this works 
new Foo(1) 

def mappedFoo = new Foo(a: '1', b: '1') 
assert mappedFoo.a == '1' 
assert mappedFoo.b == '1' 
+0

यह संभावना क्लीनर विकल्प है। –

+0

यह काम करने के लिए हुआ क्योंकि 'फू' को मूल 'ऑब्जेक्ट' कक्षा से डिफ़ॉल्ट नो-Arg कन्स्ट्रक्टर प्राप्त होता है। यदि बेस क्लास में नो-एर्ग कन्स्ट्रक्टर नहीं है तो यह टूट जाएगा, और बेस क्लास में कई कन्स्ट्रक्टर ओवरलोड होने पर यह कन्स्ट्रक्टर स्पेस को प्रदूषित करेगा। @ विल का जवाब जाने का सही तरीका है। –

7

संकलन करने पर, ग्रूवी के मानचित्र निर्माता एक object creation using an empty constructor plus a bunch of setters में अनुवाद किया जाता है (एक JavaBean शैली में)। एक खाली निर्माता होने मुद्दे को हल करती है:

class Foo { 

    Foo(Integer x) { 
    println 'my constructor was called' 
    } 

    Foo() {} 

    def a 
    def b 
} 

new Foo(1) 

foo = new Foo(a: '1', b: '2') 

assert foo.a == "1" 
4

नो आर्ग ctor जोड़ें और फोन super, उदाहरण के लिए,

class Foo { 
    Foo(Integer x) { 
    println 'my constructor was called' 
    } 

    Foo() { super() } // Or just Foo() {} 

    def a 
    def b 
} 

f = new Foo(a: '1', b: '2') 
println f.a 
=> 1 
संबंधित मुद्दे