2009-09-06 15 views
32

मुझे जावा में एक म्यूटेबल बूलियन फ़ील्ड चाहिए (मैं इस क्षेत्र को बाद में * विधि के माध्यम से वापस कर दूंगा और यह इस क्षेत्र को संशोधित करना संभव होना चाहिए)।जावा में म्यूटेबल बूलियन फ़ील्ड

बूलियन काम नहीं करता है क्योंकि बूलियन वर्ग में कोई सेट * विधियां नहीं हैं (मैं कहूंगा कि बूलियन अपरिवर्तनीय है, आप केवल संदर्भ बदल सकते हैं, लेकिन आप ऑब्जेक्ट को स्वयं नहीं बदल सकते हैं)।

मुझे लगता है कि मैं आकार 1 की बूलियन सरणी का उपयोग कर सकता हूं। लेकिन शायद अधिक सुरुचिपूर्ण समाधान हैं?

जावा की इतनी सरल चीज़ क्यों नहीं है?

+5

बूलियन मान सामान्य रूप से का उपयोग कर परीक्षण कर रहे हैं 'isXXX' तरीकों 'getXXX' – pjp

+1

@pjp' isXXX' के बजाय केवल उन प्राचीन 'बूलियन' के लिए है। हमें उन 'बूलियन' के लिए 'getXXX' पर रहना चाहिए। –

उत्तर

53

अपरिवर्तनीय कक्षाओं के साथ काम करना आसान है। वे कभी नहीं बदलेंगे और समवर्ती कोड के साथ कोई समस्या नहीं होगी। (असल में, उन्हें तोड़ने की कम संभावनाएं हैं।)

यदि आप अपने बूलियन मान का संदर्भ वापस करना चाहते हैं, तो आप java.util.concurrent.atomic.AtomicBoolean का उपयोग कर सकते हैं यदि आप एकाधिक धागे या सादे पुराने org.apache.commons.lang.mutable.MutableBoolean के साथ काम कर रहे हैं।

+2

मैंने अपने java.lang.rring टिप्पणी ऑब्जेक्ट में "mutable" लिखा था और इसे फिर से नहीं बदल सका। :-) –

+1

यह एक अंतरंग है। शायद मुझे वास्तव में परमाणु Boolean का उपयोग करना चाहिए ... धन्यवाद – javapowered

+0

एचएम .. यह मैंने javadoc में पढ़ा है: "परमाणु रूप से अद्यतन झंडे जैसे अनुप्रयोगों में एक परमाणु Boolean का उपयोग किया जाता है, और एक बूलियन के प्रतिस्थापन के रूप में इस्तेमाल नहीं किया जा सकता है।" क्यूं कर? – javapowered

4

बुलीयन आदिम का उपयोग क्यों नहीं करते?

उदा।

private boolean myFlag = false; 

public void setMyFlag(boolean flag) { 
    myFlag = flag; 
} 

नोट अपने गेटर विधि autoboxing के जादू की वजह से, एक बूलियन लौट सकते हैं यदि आवश्यक हो। यह प्राइमेटिव्स और उनके ऑब्जेक्ट समकक्षों (उदाहरण के लिए बूलियन बनाम बूलियन, या इंट बनाम इंटीजर) का उपयोग करने के बीच आसान अंतर-परिवर्तनशीलता की अनुमति देता है।

तो अपने संपादित प्रतिक्रियाओं को फिर से संबोधित करने के लिए। आपके पास उपलब्ध विधियां,

public Object getAttribute(String attributeName) 

एक ऑटोबॉक्स्ड बूलियन लौटकर कार्यान्वित किया जा सकता है।

+0

मैं कुछ सेट करने के लिए विशेष विधि नहीं जोड़ना चाहता ... सब कुछ getAttribute से लौटा ऑब्जेक्ट के माध्यम से लागू किया जाना चाहिए। ऐसा इसलिए है क्योंकि मैं बहुत शीर्ष-पदानुक्रम वर्ग इंटरफ़ेस को बदलना नहीं चाहता हूं। मुझे बस एक म्यूटेबल बूलियन ऑब्जेक्ट चाहिए ... मुझे लगता है कि java.util.concurrent.atomic.AtomicBoolean शायद सही विकल्प – javapowered

+0

जबकि मैं समझता हूं कि आप क्या कर रहे हैं, मैं कहूंगा कि मुझे यकीन नहीं है यह एक अच्छा डिजाइन है। मैं अपेक्षा करता हूं कि युक्त ऑब्जेक्ट को बदलने के लिए तीसरे पक्ष कोड को सौंपने के बजाए फ़ील्ड में हेरफेर करने की देखभाल करें। यानी यह अपने क्षेत्र की देखभाल करने और लगातार राज्य बनाए रखने के लिए युक्त वस्तु की ज़िम्मेदारी है। बस एक सिर ऊपर (आप उन बाधाओं के तहत काम कर रहे हैं जिनके बारे में मुझे पता नहीं है) –

+0

मैं उन मामलों में सहमत हूं जिन्हें हमें उपयोग नहीं करना चाहिए ऐसे अभ्यास। "findbugs" भी "खराब डिज़ाइन प्रकार" रिपोर्ट को "खराब डिज़ाइन" के रूप में रिपोर्ट करता है क्योंकि ऑब्जेक्ट को तृतीय-पक्षों द्वारा बदला जा सकता है। लेकिन इस तरह से बहुत सारे कोड पहले ही लिखे गए हैं और मुझे बस कुछ और चीजों को जोड़ने की जरूरत है :) इसके अलावा मेरे क्षेत्र के नाम से यह स्पष्ट होगा कि इसे तीसरे पक्ष द्वारा बदला जाना चाहिए, इसलिए मुझे लगता है कि इसे चाहिए एक बड़ी समस्या नहीं है :) – javapowered

4

बस बूलियन आदिम का उपयोग करने के बारे में क्या?

private boolean value; 

public void setValue(boolean value) { 
    this.value = value; 
} 

public boolean getValue() { 
    return value; 
} 
+0

यह काम करेगा लेकिन आपको प्रत्येक फ़ील्ड के लिए दो विधियां लिखनी होंगी। लेकिन मैं मौजूदा इंटरफ़ेस को बदलना नहीं चाहता हूं। मेरे पास एकमात्र तरीका है: सार्वजनिक ऑब्जेक्ट getAttrbiute (स्ट्रिंग विशेषता नाम) – javapowered

+2

इंटरफ़ेस को बदलने, सामान्य अर्थ शर्तों में, _is_ सेट करने की क्षमता जोड़ना। तो वास्तविक परिवर्तन के इंटरफेस परिवर्तन को उस परिवर्तन को ट्रैक करने और ट्रैक करने के लिए सबसे अच्छा है। – soru

+0

@soru +1 समस्या के बारे में सोचने का यह एक शानदार तरीका है। – dhable

26

हो सकता है कि अपने आप को एक आवरण वर्ग

class BooleanHolder { 
    public boolean value; 
} 

लिखने या एक सामान्य धारक वर्ग बनाने के (जिसका अर्थ है आप वर्ग Boolean बजाय आदिम boolean का उपयोग करना होगा):

class Holder<T> { 
    public T value; 
} 

आप फिर मूल्य के बजाय रैपर वर्ग को वापस करें, जो रैपर के अंदर मान को संशोधित करने की अनुमति देता है।

+4

यह काम करेगा, लेकिन आकार 1 की सरणी थोड़ा सरल है, imho :) – javapowered

+0

यदि आपको 1 से अधिक – nos

+0

की आवश्यकता है तो आप बूलियनहोल्डर्स की एक सरणी बनाते हैं, जो आपको इसे बूलियन के रूप में उपयोग करने की अनुमति नहीं देता है। –

-1

क्या आप वाकई कह रहे हैं कि आप कॉलर्स को ऑब्जेक्ट के बूलियन वैल्यू को संशोधित करने में सक्षम होना चाहते हैं जो वापस लौटाता है? ताकि ऑब्जेक्ट और कॉलर इसका संदर्भ साझा कर सके?

जैसा कि मैं समझता हूँ, यह देखते हुए:

 
class OddClass { 
    private Boolean strangeFlag; 
    public Object getAttrbiute(String attributeName) { 
     if (attributeName.equals("strangeflag")) return (Object)strangeFlag; 
     ... 
    } 
} 

और फिर फोन करने वाले से करता है:

 
    Boolean manipulableFlag = (Boolean) myOddClass.getAttrbiute ("strangeflag"); 

और फिर बाद में, फोन करने वाले manipulableFlag का मूल्य परिवर्तित करता है, यदि आप यह बदलाव में क्या करना चाहते ओडक्लास उदाहरण, जैसे कॉलर ने इसके बजाय सेटएटर्बी्यूट विधि का उपयोग किया था।

क्या आप यही पूछ रहे हैं?

उस स्थिति में, आपको एडम द्वारा सुझाए गए अनुसार धारक वर्ग की आवश्यकता होगी।

+0

यह सही है, आप समझना सही है। धारक वर्ग भारी कामकाज है। कम से कम मैं एक-तत्व सरणी का उपयोग कर सकता हूं, लेकिन शायद java.util.concurrent.atomic.AtomicBoolean सबसे अच्छा विकल्प है – javapowered

19

आप जावा 5 या अधिक उपयोग कर रहे हैं तो AtomicBoolean

+6

@monzonj: 'java.util.concurrent' कक्षाएं' सिंक्रनाइज़ 'का उपयोग नहीं करती हैं, वे बहुत बेहतर उपयोग करते हैं ऑप्टिमाइज्ड लॉकिंग संरचनाएं। 'बुलियन' के लिए निहित होने पर 'परमाणु बूलियन' का एक पूरी तरह से महत्वहीन प्रदर्शन ओवरहेड होगा। यदि आप अन्यथा प्रदर्शित कर सकते हैं, तो कृपया हमें दिखाएं। – skaffman

+5

@monzonj: किसी भी मामले में इसका कोई महत्वपूर्ण प्रदर्शन ओवरहेड नहीं है। सही नौकरी के लिए सही उपकरण का उपयोग करने से भी बहुत कुछ हासिल किया जा सकता है। कुछ माइक्रो-प्रदर्शन हिट के बारे में आप जो सोचते हैं उसके बावजूद आप माप नहीं सकते हैं, इस अत्यधिक अनुकूलित वर्ग को किसी कारण से बनाया गया था, मुझे संदेह है कि आप बेहतर कर सकते हैं। –

+2

@monzonj - आपका दावा है कि * "परमाणु असाइनमेंट केवल सिंक्रनाइज़ेशन के माध्यम से किया जा सकता है" * सबसे अच्छी तरह से गलत जानकारी दी गई है, * लॉक फ्री सिंक्रनाइज़ेशन * की अवधारणा है और यदि आप वास्तव में 'परमाणु बूलियन' के स्रोत को देखते हैं तो आप करेंगे देखें कि कहीं भी 'सिंक्रनाइज़' कीवर्ड का कोई उपयोग नहीं है! आप अपनी अनौपचारिक टिप्पणी के साथ गलत तरीके से गलत जानकारी फैल रहे हैं। –

3

का उपयोग आप Android का उपयोग कर रहे हैं, तो आप एक बूलियन सरणी

final boolean[] values = { false }; 
values[0] = true; 
0

उपयोग कर सकते हैं, तो आप android.util.Mutable * वस्तुओं का उपयोग कर सकते हैं जो विभिन्न आदिम मूल्यों को लपेटें। उदाहरण के लिए, एसडीके स्रोत से उद्धृत:

public final class MutableBoolean { 
    public boolean value; 

    public MutableBoolean(boolean value) { 
     this.value = value; 
    } 
} 
1

जवाब मैं इसे पसंद किया सबसे अपने स्वयं के आवरण वर्ग लिखने के लिए एडम से था ... ठीक

/* Boolean to be passed as reference parameter */ 
public class Bool { 

    private boolean value; 

    public Bool() { 
     this.value = false; 
    } 

    public boolean is() { 
     return this.value; 
    } 

    public void setTrue() { 
     this.value = true; 
    } 

    public void setFalse() { 
     this.value = false; 
    } 
} 
संबंधित मुद्दे