2008-09-16 12 views
51

तो, मैंने जानबूझकर हाल ही में जावा एन 00 बी रखा है, और मेरा पहला वास्तविक एक्सपोजर मामूली सदमे लाया: जावा में सी # शैली गुण नहीं हैं!(नहीं) जावा में गुण?

ठीक है, मैं इसके साथ रह सकता हूं। हालांकि, मैं यह भी कसम खाता हूं कि मैंने एक कोडबेस में जावा में प्रॉपर्टी गेटर/सेटर कोड देखा है, लेकिन मुझे याद नहीं है। यह कैसे प्राप्त किया गया था? क्या इसके लिए कोई भाषा विस्तार है? क्या यह नेटबीन या कुछ से संबंधित है?

उत्तर

59

जावा में गेटर्स और सेटर्स के लिए "मानक" पैटर्न है, जिसे Bean properties कहा जाता है। मूल रूप से get से शुरू होने वाली कोई भी विधि, कोई तर्क नहीं लेना और मूल्य वापस करना, संपत्ति के बाकी नाम के रूप में नामित संपत्ति के लिए एक संपत्ति गेटटर है (कम शुरूआती प्रारंभ पत्र के साथ)। इसी तरह set एक एकल विधि के साथ एक शून्य विधि का एक सेटटर बनाता है।

उदाहरण के लिए:

// Getter for "awesomeString" 
public String getAwesomeString() { 
    return awesomeString; 
} 

// Setter for "awesomeString" 
public void setAwesomeString(String awesomeString) { 
    this.awesomeString = awesomeString; 
} 

अधिकतर जावा IDEs अगर आप उन्हें पूछना (ग्रहण में यह एक क्षेत्र के लिए कर्सर ले जाकर और ctrl-1 से टकराने के रूप में सरल है आप के लिए इन तरीकों उत्पन्न होगा, तो विकल्प का चयन सूची से)।

क्या यह आप वास्तव में भी बूलियन प्रकार की संपत्तियों के लिए get के स्थान पर is और has उपयोग कर सकते हैं, के रूप में के लायक है, पठनीयता के लिए के लिए:

public boolean isAwesome(); 

public boolean hasAwesomeStuff(); 
+0

मैं कसम खाता हूँ सकता है मैं सी # शैली की संपत्ति कहीं वाक्य रचना कुछ जावा कोड में देखा है, लेकिन के लिए मेरे जीवन में मुझे याद नहीं है कि कैसे और कैसे। यह वास्तव में मेरे प्रश्न का उत्तर नहीं देता है लेकिन मैं इसे असाधारण कारक के लिए स्वीकार करूंगा। शायद मैं फिर से हेलुसिनेट कर रहा हूं। – Ishmaeel

+0

मुझे यकीन है कि यह जावा में नहीं किया जा सकता है, क्षमा करें। ऐसी कई जेवीएम भाषाएं हैं जिनके पास इस तरह की चीज के लिए प्रथम श्रेणी का समर्थन है, हालांकि, शायद आपने यही देखा है? – Calum

+0

क्या यह इस सम्मेलन का उल्लंघन है यदि आप किसी सदस्य चर को 'm',' m_', या '_' जैसे उपसर्ग करते हैं, लेकिन फिर आप उस उपसर्ग को संपत्ति के नाम में शामिल नहीं करते हैं? – Panzercrisis

2

मेरा जावा अनुभव इतना उच्च नहीं है, इसलिए कोई भी मुझे सही करने के लिए स्वतंत्र महसूस करता है।

public string getMyString() { 
    // return it here 
} 

public void setMyString(string myString) { 
    // set it here 
} 
1

आप ग्रहण का उपयोग कर रहे तो यह स्वत: करने के लिए क्षमता है आंतरिक विशेषताओं के लिए गेटर और सेटर विधि उत्पन्न है, यह एक उपयोगी हो सकता है: लेकिन AFAIK, सामान्य सम्मेलन दो विधियों इसलिए की तरह लिखना है और टाइमविंग उपकरण।

5

सेम सम्मेलन इस तरह कोड लिखने के लिए:

private int foo; 
public int getFoo() { 
    return foo; 
} 
public void setFoo(int newFoo) { 
    foo = newFoo; 
} 

JVM, जैसे, ग्रूवी पर अन्य भाषाओं में से कुछ में, आप, सी # के समान overridable गुण, जैसे मिल

int foo 

जिसे एक साधारण .foo के साथ उपयोग किया जाता है और डिफ़ॉल्ट getFoo और setFoo कार्यान्वयन करता है जो आप आवश्यकतानुसार ओवरराइड कर सकते हैं।

3

जावा के लिए सबसे IDEs स्वचालित रूप से गेटर और सेटर कोड उत्पन्न होगा यदि आप उन्हें चाहते हैं तो आपके लिए। कई अलग-अलग सम्मेलन हैं, और ग्रहण जैसे आईडीई आपको यह चुनने की अनुमति देंगे कि आप किस का उपयोग करना चाहते हैं, और यहां तक ​​कि आप स्वयं को परिभाषित भी करते हैं।

ग्रहण में स्वचालित रीफैक्टरिंग भी शामिल है जो आपको गेटटर और सेटर में एक संपत्ति को लपेटने की अनुमति देगी और यह गेटटर और/या सेटर का उपयोग करने के लिए सीधे उस संपत्ति को एक्सेस करने वाले सभी कोड को संशोधित करेगी।

बेशक, ग्रहण केवल उस कोड को संशोधित कर सकता है जो इसके बारे में जानता है - आपके द्वारा किसी भी बाहरी निर्भरता को इस तरह के रिफैक्टरिंग द्वारा तोड़ दिया जा सकता है।

5

जावा 7 के लिए "जावा प्रॉपर्टी सपोर्ट" का प्रस्ताव था, लेकिन इसे भाषा में नहीं बनाया गया।

रुचि रखते हैं तो अधिक लिंक और जानकारी के लिए http://tech.puredanger.com/java7#property देखें।

1

मैं सिर्फ जावा 5/6 एनोटेशन और एनोटेशन प्रोसेसर को इस में मदद करने के लिए रिलीज़ कर रहा हूं।

चेक बाहर http://code.google.com/p/javadude/wiki/Annotations

प्रलेखन थोड़ा प्रकाश अभी है, लेकिन quickref भर में विचार मिलना चाहिए।

मूल रूप से यह गेटर्स/सेटर्स (और कई अन्य कोड जनरेशन विकल्पों) के साथ एक सुपरक्लास उत्पन्न करता है।

एक नमूना वर्ग लग सकता है की तरह

@Bean(properties = { 
    @Property(name="name", bound=true), 
    @Property(name="age,type=int.class) 
}) 
public class Person extends PersonGen { 
} 

वहाँ कई और अधिक नमूने उपलब्ध हैं, और वहाँ उत्पन्न कोड में कोई क्रम निर्भरता है।

यदि आप इसे आज़माते हैं और इसे उपयोगी पाते हैं तो मुझे एक ईमेल भेजें! - स्कॉट

6
public class Animal { 

    @Getter @Setter private String name; 
    @Getter @Setter private String gender; 
    @Getter @Setter private String species; 
} 

यह सी # गुणों की तरह कुछ है। यह http://projectlombok.org/

+1

ध्यान दें: यह भाषा विस्तार के रूप में गिना जाएगा, और आईडीई को बहुत उलझन में डालता है। – millimoose

+2

@millimoose आपको सिर्फ आईडीई के लिए एक प्लगइन चाहिए। दुख की बात है कि इस तरह के कोड का उपयोग करने वाले हर किसी को इसकी जरूरत है। – dantuch

+2

"आपको आईडीई के लिए एक प्लगइन चाहिए" मुझे एक समाचार पत्र खोलना और इसके लिए जिम्मेदार व्यक्ति को स्वाट करना चाहता है। (हालांकि तर्कसंगत रूप से उन मामलों में अधिक है जहां आईडीई कॉन्फ़िगरेशन कोडबेस के लिए प्राथमिक निर्माण प्रणाली है।) – millimoose

29

मुझे आश्चर्य है कि कोई भी उल्लेख किया project lombok

हाँ हूँ है, वर्तमान में वहाँ जावा में कोई गुण हैं। कुछ अन्य गायब विशेषताएं भी हैं।
लेकिन सौभाग्य से हमारे पास project lombok है जो स्थिति को बेहतर बनाने की कोशिश कर रहा है। यह हर दिन अधिक से अधिक लोकप्रिय हो रहा है।

तो, आप lombok उपयोग कर रहे हैं:

@Getter @Setter int awesomeInteger = 5; 

इस कोड getAwesomeInteger और setAwesomeInteger रूप में अच्छी तरह उत्पन्न करने के लिए जा रहा है। तो यह C# auto-implemented properties के समान है।

आप लोम्बोक गेटर्स और सेटर्स here के बारे में अधिक जानकारी प्राप्त कर सकते हैं।
आपको निश्चित रूप से other features भी देखना चाहिए। मेरे पसंदीदा हैं:

लंबोक IDEs के साथ अच्छी तरह से एकीकृत है, इसलिए ऐसा लगता है कि अगर वे अस्तित्व में उत्पन्न तरीकों को दिखाने के लिए जा रहा है (सुझाव, वर्ग सामग्री, घोषणा और refactoring पर जाएं)।
लोम्बोक के साथ एकमात्र समस्या यह है कि अन्य प्रोग्रामर शायद इसके बारे में नहीं जानते। आप कोड delombok कोड कर सकते हैं लेकिन यह एक समाधान की तुलना में एक कामकाज है।

+3

जिन तरीकों से आप कोड में नहीं देख पा रहे हैं, वे भी बदतर लगते हैं। सी # में ऑटो-प्रॉपर्टी केवल सचमुच आधे कहानी हैं - यह ज्यादातर नामकरण और संबंधित तर्क को समूहीकृत करने के बारे में है। –

+6

@ जॉनीलेड्स अच्छी तरह से, यह बिल्कुल बुरा कैसे है? आप '' गेटटर'' और '@ सेटर' एनोटेशन को स्पॉट करके कोड में देख सकते हैं, और वे अन्य टूलबार में भी दिखाए जाते हैं (जैसे रूपरेखा या सुझाव) –

+0

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

2

से जेफरी रिक्टर की पुस्तक के माध्यम से CLR सी #: (मुझे लगता है कि इन वजहों गुण अभी भी जावा में नहीं जोड़े जाते हैं हो सकता है)

  • एक संपत्ति विधि एक अपवाद फेंक कर सकते हैं; क्षेत्र का उपयोग कभी अपवाद फेंकता नहीं है।
  • एक संपत्ति को out या ref पैरामीटर के रूप में पारित नहीं किया जा सकता है; एक क्षेत्र कर सकते हैं।
  • एक संपत्ति विधि एक लंबे समय निष्पादित करने के लिए ले जा सकते हैं; फ़ील्ड एक्सेस हमेशा को पूरा करता है। एक आम कारण गुण का उपयोग करने के धागा तुल्यकालन, जो धागा हमेशा के लिए बंद कर सकते हैं, और इसलिए, एक संपत्ति नहीं किया जाना चाहिए अगर धागा तुल्यकालन की आवश्यकता है प्रदर्शन करने के लिए है। उस स्थिति में, एक विधि को प्राथमिकता दी जाती है। इसके अलावा, यदि आपकी कक्षा को दूरस्थ रूप से एक्सेस किया जा सकता है (उदाहरण के लिए, आपकी कक्षा System.MarshalByRefObject से ली गई है), तो संपत्ति विधि को कॉल करना बहुत धीमा होगा, और इसलिए, किसी विधि को एक विधि पसंद की जाती है। मेरी राय में, MarshalByRefObject से प्राप्त कक्षाएं कभी भी गुणों का उपयोग नहीं करनी चाहिए।
  • यदि पंक्ति में कई बार कहा जाता है, तो एक प्रॉपर्टी विधि प्रत्येक समय पर एक अलग मान वापस कर सकती है; एक फ़ील्ड हर बार एक ही मूल्य देता है। System.DateTime वर्ग एक केवल पढ़ने के लिए Now संपत्ति है कि वर्तमान दिनांक और समय देता है। प्रत्येक बार जब आप यह संपत्ति पूछते हैं, तो यह एक अलग मान वापस कर देगा। यह एक गलती है, और माइक्रोसॉफ्ट चाहता है कि वे अब संपत्ति के बजाय एक विधि बनाकर कक्षा को ठीक कर सकते हैं। Environment के TickCount संपत्ति इस गलती का एक और उदाहरण है।
  • एक संपत्ति विधि नमूदार दुष्प्रभाव हो सकता है; क्षेत्र का उपयोग कभी नहीं करता है। अन्य शब्दों में, किसी प्रकार का उपयोगकर्ता में किसी भी प्रकार द्वारा परिभाषित विभिन्न गुणों को सेट करने में सक्षम होना चाहिए, वह किसी भी क्रम में किसी भी प्रकार के व्यवहार को ध्यान में रखे बिना चुनता है।
  • एक संपत्ति विधि को अतिरिक्त मेमोरी की आवश्यकता हो सकती है या का संदर्भ वापस कर सकता है जो वास्तव में ऑब्जेक्ट के राज्य का हिस्सा नहीं है, इसलिए लौटा ऑब्जेक्ट को संशोधित करने से मूल ऑब्जेक्ट पर प्रभाव नहीं होता है; किसी फ़ील्ड से पूछताछ हमेशा ऑब्जेक्ट का संदर्भ देता है जो मूल ऑब्जेक्ट के राज्य का हिस्सा होने की गारंटी देता है। एक संपत्ति के साथ काम करना जो एक प्रतिलिपि देता है डेवलपर्स के लिए बहुत भ्रमित हो सकता है, और यह विशेषता अक्सर दस्तावेज नहीं है।
+2

"" यह एक गलती है, और माइक्रोसॉफ्ट चाहता है कि वे अब संपत्ति के बदले एक विधि बनाकर कक्षा को ठीक कर सकें "" क्या इसका कोई सबूत है? "गेटटर और सेटर विधियों" के साथ सभी शब्द "संपत्ति" को प्रतिस्थापित करने का प्रयास करें और फिर से पढ़ें। पाठ अभी भी सटीक होना चाहिए और यही कारण है कि मुझे इस तरह के तर्क मूर्खतापूर्ण लगता है। मेरी राय में, यह सिर्फ "मुझे समझ में नहीं आता कि संपत्ति क्या है, इसलिए मुझे यह पसंद नहीं है" ... अच्छी तरह से संपत्ति गेटटर और सेटर विधियों के लिए सिर्फ अनुकूल वाक्यविन्यास है ... तो यदि आप नहीं करते हैं गुणों की तरह, तो आप गेटर और सेटर्स की तरह शॉल नहीं करते ... – Jens

3

आप के लिए की जरूरत नहीं हो सकता है "सेट" उपसर्ग, यह अधिक गुण की तरह लग रहे बनाने के लिए "मिल" और, आप इसे इस तरह से कर सकते हैं:

public class Person { 
    private String firstName = ""; 
    private Integer age = 0; 

    public String firstName() { return firstName; } // getter 
    public void firstName(String val) { firstName = val; } // setter 

    public Integer age() { return age; } // getter 
    public void age(Integer val) { age = val; } //setter 

    public static void main(String[] args) { 
     Person p = new Person(); 

     //set 
     p.firstName("Lemuel"); 
     p.age(40); 

     //get 
     System.out.println(String.format("I'm %s, %d yearsold", 
      p.firstName(), 
      p.age()); 
    } 
} 
1

जावा में कोई संपत्ति कीवर्ड नहीं है (आप सी # में यह मिल सकता है की तरह) 1 शब्द गेटर के लिए निकटतम रास्ता/सेटर सी में की तरह करना है ++:

public class MyClass 
{ 
    private int aMyAttribute; 
    public MyClass() 
    { 
     this.aMyAttribute = 0; 
    } 
    public void mMyAttribute(int pMyAttributeParameter) 
    { 
     this.aMyAttribute = pMyAttributeParameter; 
    } 
    public int mMyAttribute() 
    { 
     return this.aMyAttribute; 
    } 
} 
//usage : 
int vIndex = 1; 
MyClass vClass = new MyClass(); 
vClass.mMyAttribute(vIndex); 
vIndex = 0; 
vIndex = vClass.mMyAttribute(); 
// vIndex == 1 
संबंधित मुद्दे