2016-04-23 14 views
5

मैं एक अनुकूलित वर्ग के लिए एक क्षेत्र के रूप में जावा क्लास BitSet का उपयोग करने की कोशिश कर रहा हूं। और मैं कक्षा को सभी बिट्स सेट के साथ एक डिफ़ॉल्ट बिटसेट का उपयोग करना चाहता हूं।ऑब्जेक्ट इंस्टेंटेशन के साथ विधि कॉल ऑब्जेक्ट को ऑब्जेक्ट कर सकता है?

import java.util.BitSet; 

public class MyClass { 
    private BitSet mask; 

    public MyClass() { 
     this(new BitSet(4)); 
     // want to set all bits first 
     // something like 
     // this(new BitSet(4).set(0,3)); 
    } 

    public MyClass(BitSet mask) { 
     this.mask = mask; 
    }  
} 

डिफ़ॉल्ट BitSet निर्माता unsets सभी बिट्स तक। तो इससे पहले कि मैं इसे एक अज्ञात वस्तु के रूप में भेजूं, मैं सभी बिट्स सेट करने के लिए set(int, int) विधि को कॉल करना चाहता हूं। मुझे पता है कि मैं बस mask को नए BitSet पर प्रारंभ कर सकता हूं और फिर वहां से set(int, int) विधि को कॉल कर सकता हूं।

हालांकि, आम तौर पर मुझे आश्चर्य है कि ऑब्जेक्ट इंस्टेंटेशन के समय एक इंस्टेंस विधि तक पहुंच बनाना संभव है?

उत्तर

3

क्यों एक अलग कन्स्ट्रक्टर लिखना नहीं है जो BitSet प्रारंभिकरण की अनुमति देता है?,

public static <T> T initialize(T t,Consumer<T> initializer) { 
    initializer.accept(t); 
    return t; 
} 

उस मामले में पहले MyClass होगा: जावा 8 का उपयोग करना, यह कुछ इस तरह दिखाई देगा:

public class MyClass { 
    private BitSet mask; 
    public MyClass() { 
    this(new BitSet(4),(m)->m.set(0,3)); 
    } 
    public MyClass(BitSet mask,Consumer<BitSet> initializer) { 
    initializer.accept(mask); 
    this.mask = mask; 
    } 
} 

तुम भी है कि अधिक सामान्य बना सकते हैं प्रकार पैरामीटर के साथ एक स्थिर विधि शुरू करने से कुछ ऐसा नज़र:

public class MyClass { 
    private BitSet mask; 
    public MyClass() { 
    this(initialize(new BitSet(4),(m)->m.set(0,3))); 
    } 
    public MyClass(BitSet mask) { 
    this.mask = mask; 
    } 
} 

अद्यतन

और वहाँ नए तरीकों या कंस्ट्रक्टर्स शुरू करने के बिना एक और तरीका है,:

public class MyClass { 
    private BitSet mask; 
    public MyClass() { 
    this(new BitSet(4) {{ set(0,3); }}); 
    } 
    public MyClass(BitSet mask) { 
    this.mask = mask; 
    } 
} 

एक anonymous classBitSet विस्तार और इसलिए double curly braces एक instance initialization block, जोड़कर instantiated जा रहा है।

+0

मैं जेनेरिक में बहुत कमजोर हूं। लेकिन उपरोक्त वही है जो मैं ढूंढ रहा हूं। यह संक्षेप में है और मुझे 'इस' ऑपरेटर का उपयोग करने की अनुमति भी देता है। फिर मेरे पास गैर-डिफ़ॉल्ट कन्स्ट्रक्टर में सामान्य प्रारंभिक कोड हो सकता है। धन्यवाद! –

+0

आपके द्वारा जोड़े गए तीसरे विकल्प। इस दृष्टिकोण के लिए शब्द क्या है, यदि कोई है? –

+0

यह एक 'इंस्टेंस प्रारंभकर्ता ब्लॉक' है, लेकिन जैसा कि यह एक अज्ञात वर्ग के शरीर के भीतर दिखाई देता है, ऐसा लगता है कि यह कुछ विशेष वाक्यविन्यास है (यह नहीं है)। इसी कारण से, लोग अक्सर इसे 'डबल ब्रेसेस' मुहावरे के रूप में संदर्भित करते हैं (http://stackoverflow.com/questions/1958636/what-is-double-brace-initialization-in-java)। इसे अक्सर [एंटी-पैटर्न] में वर्णित किया जाता है (https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/) घोंसला संग्रह प्रारंभिकरण के लिए । हालांकि, यहां जिस तरह से पेश किया गया है वह ठीक होना चाहिए। – YoYo

0

नहीं; जिसे एक अलग कॉल के रूप में किया जाना होगा, जिसे के बाद निष्पादित किया जाएगा, ऑब्जेक्ट का निर्माण समाप्त हो गया है। अपनी स्थिति में एक पंक्ति में यह करने के लिए एक ही रास्ता है, तो विधि की वापसी प्रकार BitSet गया था और विधि उदाहरण उस पर लागू किया गया था, जिस स्थिति में आप

this(new BitSet(4).set(0, 1)); // Doesn't actually work 

दुर्भाग्य से कर सकते थे लौटा था है, set()void है, इसलिए आप यह नहीं कर सकते हैं।

2

बिटसेट में धाराप्रवाह इंटरफ़ेस नहीं है, इसलिए new BitSet(4).set(0,3) जैसे कुछ बिट्ससेट के लिए काम नहीं करते हैं। केवल स्थिर BitSet.valueOf() विधियां हैं, लेकिन वे उपयोग करने के लिए कुछ हद तक अजीब हैं। हालांकि, यदि आप एक स्थिर कॉन्फ़िगरेशन चाहते हैं तो आप वांछित मान के साथ बस बिटसेट को तुरंत चालू कर सकते हैं, BitSet.toLongArray() का उपयोग करें, सरणी मानों को प्रिंट करें और इसके साथ अपने बिटसेट को तुरंत चालू करें। अपने विशिष्ट उदाहरण में डिफ़ॉल्ट निर्माता हो सकता है:

public MyClass() { 
    this(BitSet.valueOf(new long[]{7})); 
} 

प्रश्न के सामान्य भाग के लिए के रूप में: यह केवल काम करेगा यदि आप एक "सेटर" है कि मौजूदा ऑब्जेक्ट है, कि श्रृंखला के लिए आप की अनुमति होगी कहता है। आप इस तरह से कुछ कर सकते हैं तो अपने स्वयं के कक्षाओं के लिए:

public class A { 
    private int num; 

    public int getNum() { 
     return num; 
    } 
    public void setNum(int num) { 
     this.num = num; 
    } 
    public A withNum(int num) { 
     setNum(num); 
     return this; 
    } 
} 

अगर आपको लगता है कि BitSet साथ की तरह एक निर्माता में आप this(new A().withNum(4));

Fluent इंटरफेस बहुत लोकप्रिय हैं कर सकते हैं (इस्तेमाल किया जैसे एडब्ल्यूएस एसडीके कि है हर जगह), केवल जेडीके वस्तुओं में उन्हें आमतौर पर नहीं होता है।

संबंधित मुद्दे