पृष्ठ पलटने के लिए स्क्रॉल करें
Computer Science A · AP Computer Science A
मान, रेफ़रेंस और उन्हें उपयोग करने वाले मेथड
वेरिएबल मेमोरी में एक नामित डिब्बा है। प्रिमिटिव वेरिएबल अपना मान रखता है; रेफ़रेंस वेरिएबल किसी ऑब्जेक्ट का स्थान रखता है।
int score = 42; int copy = score; // कॉपी को अपना 42 मिलता है copy = 7; // score अब भी 42 है String name = "Ada"; // एक रेफ़रेंस String other = name; // वही रेफ़रेंस
चित्र ये पंक्तियाँ चलाता है। copy = score मान 42 को दूसरे डिब्बे में कॉपी करता है, इसलिए जब copy का मान 7 हो जाता है, तब score जस का तस रहता है। name में कोई वर्ण है ही नहीं: उसके डिब्बे में एक तीर (लाल) है जो मेमोरी में कहीं और बने String ऑब्जेक्ट की ओर इशारा करता है। other = name तीर की कॉपी बनाता है, ऑब्जेक्ट की नहीं: दो तीर, एक ऑब्जेक्ट।
यह अंतर पूरे Java में और इस अध्याय में चलता है: वेरिएबल क्या रखता है, मेथड को क्या दिया जाता है और वह क्या लौटाता है, new क्या बनाता है, और String एक बार बनने के बाद कभी क्यों नहीं बदलता।
यह अध्याय AP Computer Science A की इकाई 1, ऑब्जेक्ट और मेथड का उपयोग है, जो बहुविकल्पीय अंकों का 15–25% है: कंपाइल करना और त्रुटियाँ (1.1), टाइप, एक्सप्रेशन और असाइनमेंट (1.2–1.6), लाइब्रेरी, डॉक्यूमेंटेशन और मेथड (1.7–1.11), ऑब्जेक्ट और उनका निर्माण (1.12–1.14) और String (1.15)। परीक्षा के 42 बहुविकल्पीय प्रश्नों के साथ Java Quick Reference मिलती है, जिसमें वे सभी लाइब्रेरी मेथड हैं जिनका उपयोग हो सकता है; इसका पहला मुक्त-उत्तर प्रश्न String मेथड कॉल करता है।
और तीन तरह की त्रुटियाँ
एल्गोरिदम किसी कार्य को पूरा करने या किसी समस्या को हल करने की चरण-दर-चरण प्रक्रिया है। इसे शब्दों में लिखा जा सकता है, आरेख में बनाया जा सकता है, या प्रोग्राम के रूप में लिखा जा सकता है।
सीक्वेंसिंग चरणों को क्रम में रखती है, और वे एक-एक करके चलते हैं: Java मेथड अपने स्टेटमेंट ऊपर से नीचे चलाता है, जब तक कुछ प्रवाह को न बदल दे।
कोड किसी भी टेक्स्ट एडिटर में लिखा जा सकता है, पर अधिकतर प्रोग्रामर इंटीग्रेटेड डेवलपमेंट एनवायरनमेंट (IDE) का उपयोग करते हैं, जिसमें कोड लिखने, कंपाइल करने और चलाने के औज़ार होते हैं। कंपाइलर सोर्स में कुछ त्रुटियाँ जाँचता है और उसका अनुवाद करता है; Java का कंपाइलर बाइटकोड बनाता है, जिसे Java Virtual Machine (JVM) चलाती है। कंपाइलर जो त्रुटियाँ खोजता है, प्रोग्राम चलने से पहले उन्हें ठीक करना होगा।
चित्र तीन प्रोग्राम को पंक्ति में भेजता है, हर एक में एक तरह की त्रुटि है।
int total = 7 + 3 // ; छूट गया System.out.println(total); सिंटैक्स त्रुटि भाषा के नियम तोड़ती है। कंपाइलर इसे खोज लेता है (error: ';' expected) और कुछ भी नहीं चलता।
int count = 0; System.out.println(10 / count);
रन-टाइम त्रुटि प्रोग्राम चलते समय होती है, और आमतौर पर उसे असामान्य रूप से समाप्त कर देती है। यह एक अपवाद (एक्सेप्शन) है: ऐसी त्रुटि जिसे कंपाइलर नहीं पकड़ पाया, और जो निष्पादन के सामान्य प्रवाह को बीच में रोक देती है (ArithmeticException: / by zero)।
double avg = (7 + 8) / 2; System.out.println(avg); // prints 7.0 लॉजिक त्रुटि कंपाइल होती है और चलती है, पर गलत व्यवहार करती है: 7 and 8 का औसत 7.5 होना चाहिए। इसे केवल विशिष्ट डेटा से परीक्षण करके और अपेक्षित परिणाम से तुलना करके ही खोजा जा सकता है। (यह 7.0 क्यों प्रिंट करता है: पृष्ठ 1.3।)
int, double, boolean और रेफ़रेंस
डेटा टाइप मानों का एक समूह और उन पर होने वाली संक्रियाओं का समूह है। हर टाइप या तो प्रिमिटिव होता है या रेफ़रेंस टाइप।
पाठ्यक्रम में तीन प्रिमिटिव टाइप उपयोग होते हैं, संख्याओं और बूलियन मानों के लिए:
| type | values | examples |
|---|---|---|
int | integers | 7, -40, 0 |
double | वास्तविक संख्याएँ | 2.5, 7.0, -0.01 |
boolean | true या false | true |
Java में पाँच अन्य प्रिमिटिव टाइप हैं (long, short, byte, float, char); वे पाठ्यक्रम और परीक्षा से बाहर हैं। जो कुछ प्रिमिटिव नहीं है, जैसे String, वह ऑब्जेक्ट है, और उसका टाइप रेफ़रेंस टाइप है।
वेरिएबल एक स्टोरेज स्थान है जो एक मान रखता है, जो प्रोग्राम चलते समय बदल सकता है। हर वेरिएबल का एक नाम और एक टाइप होता है, और प्रिमिटिव टाइप का वेरिएबल उसी टाइप का मान रखता है।
int n = 7; double d = 2.5; boolean ठीक = true; double w = 7; // stores 7.0 int m = 2.5; // कंपाइल नहीं होता
int, double में समा जाता है: double w = 7; में 7.0 संग्रहीत होता है। double, int में नहीं समाता, इसलिए int m = 2.5; कंपाइल त्रुटि है: incompatible types: possible lossy conversion from double to int।
टाइप इस आधार पर चुनें कि मान क्या हो सकता है: विद्यार्थियों की गिनती int है, कीमत या औसत double, और बत्ती जल रही है या नहीं boolean।
print, println और एस्केप सीक्वेंस
System.out.print और System.out.println स्क्रीन पर जानकारी दिखाते हैं। println उसके बाद कर्सर को नई पंक्ति पर ले जाता है; print उसे वहीं छोड़ देता है।
लिटरल किसी स्थिर मान का कोड में रूप है: 7, 2.5, true। स्ट्रिंग लिटरल दोहरे उद्धरण चिह्नों में वर्णों का क्रम है: "CSA"।
कुछ वर्णों को उद्धरण चिह्नों के भीतर सीधे नहीं लिखा जा सकता। एस्केप सीक्वेंस बैकस्लैश से शुरू होता है और उसका विशेष अर्थ होता है। पाठ्यक्रम में तीन उपयोग होते हैं:
| एस्केप सीक्वेंस | means |
|---|---|
\" | एक दोहरा उद्धरण चिह्न |
\\ | एक बैकस्लैश |
\n | एक नई पंक्ति |
System.out.print("AP "); System.out.println("CSA"); System.out.println("say \"hi\""); System.out.print("a\\b\nc"); कंसोल तब यह दिखाता है (चित्र इसे टाइप करके दिखाता है):
AP CSA say "hi" a\b c पहला print कर्सर को AP के बाद छोड़ देता है, इसलिए CSA उसी पंक्ति में आता है। अंतिम पंक्ति में \\ एक बैकस्लैश प्रिंट करता है और \n स्ट्रिंग के बीच में नई पंक्ति शुरू करता है।
int भाग, शेषफल और प्राथमिकता
अंकगणितीय एक्सप्रेशन संख्यात्मक मानों, वेरिएबलों और ऑपरेटर +, -, *, / और % को जोड़ता है। दो int मान int देते हैं; कम से कम एक double हो तो परिणाम double होता है।
System.out.println(17 / 5); // 3 System.out.println(17 % 5); // 2 System.out.println(17.0 / 5); // 3.4
दो int को भाग देने पर भागफल का केवल पूर्णांक भाग रहता है: 17 ब्लॉक से 5 के 3 पूरे समूह बनते हैं। शेषफल ऑपरेटर % बचा हुआ देता है: 2। भाग में कोई double हो तो परिणाम स्वयं भागफल होता है, 3.4। (पाठ्यक्रम में % केवल a ≥ 0 और b > 0 के साथ उपयोग होता है।)
प्राथमिकता: *, / और %, + और - से पहले लगते हैं; समान प्राथमिकता वाले ऑपरेटर बाएँ से दाएँ चलते हैं; कोष्ठक समूहन बदल देते हैं। कंपाइलर कंपाइल के समय मानों को उनके ऑपरेटरों के साथ इसी तरह समूहित करता है।
| expression | value |
|---|---|
2 + 3 * 4 | 14 |
(2 + 3) * 4 | 20 |
10 - 4 - 3 | 3 |
7 + 9 % 4 | 8 |
1 / 2 * 4.0 | 0.0 |
1.0 / 2 * 4 | 2.0 |
1 / 2 * 4.0 में 1 / 2 int भाग है और double के आने से पहले ही 0 हो चुका होता है।
किसी int को int शून्य से भाग देने पर पंक्ति चलते समय ArithmeticException फेंका जाता है। (double से शून्य का भाग और उससे बनने वाले विशेष double मान पाठ्यक्रम से बाहर हैं।)
दायाँ पक्ष, बाईं ओर संग्रहीत
असाइनमेंट ऑपरेटर = अपनी दाईं ओर के एक्सप्रेशन का मूल्यांकन करके एक मान निकालता है और उसे अपनी बाईं ओर के वेरिएबल में संग्रहीत करता है।
किसी एक्सप्रेशन में उपयोग करने से पहले वेरिएबल को मान देना ज़रूरी है, और वह मान संगत टाइप का होना चाहिए। पहला असाइनमेंट उसे इनिशियलाइज़ करता है। बाद का हर असाइनमेंट मान को बदल देता है: पुराना मान चला जाता है।
int a = 3; // a 3 int b = 8; // a 3, b 8 int temp = a; // a 3, b 8, temp 3 a = b; // a 8, b 8, temp 3 b = temp; // a 8, b 3, temp 3
इसीलिए दो वेरिएबलों की अदला-बदली में तीसरे की ज़रूरत पड़ती है। temp के बिना a = b a के 3 को नष्ट कर देता, इससे पहले कि b उसे ले पाता। चित्र हर प्रति को एक डिब्बे से दूसरे में ले जाता है: स्रोत अपना मान रखता है।
प्रोग्राम चलने पर एक्सप्रेशन का मूल्यांकन एक मान में होता है, और उस मान का एक टाइप होता है: a + b एक int है, a + 0.5 एक double। count = count + 1 जैसा स्टेटमेंट समीकरण नहीं है; यह count को पढ़ता है, उसमें 1 जोड़ता है और परिणाम वापस संग्रहीत करता है।
रेफ़रेंस वेरिएबल को नया ऑब्जेक्ट या null असाइन किया जा सकता है। लिटरल null का अर्थ है कि रेफ़रेंस किसी ऑब्जेक्ट से जुड़ा नहीं है।
एक्सप्रेशन के भीतर असाइनमेंट, जैसे a = b = 4;, पाठ्यक्रम से बाहर हैं।
इनपुट स्पर्श, ध्वनि, दृश्य या टेक्स्ट रूप में हो सकता है। Scanner क्लास कीबोर्ड से टाइप किया टेक्स्ट पढ़ने का एक तरीका है; परीक्षा में उपयोगकर्ता इनपुट के किसी विशिष्ट रूप की जाँच नहीं होती।
ट्रंकेट करना, चौड़ा करना और पूर्णांकन
कास्टिंग ऑपरेटर (int) और (double) किसी मान को एक प्रिमिटिव टाइप से दूसरे में बदलते हैं।
double को int में कास्ट करने पर वह ट्रंकेट होता है: दशमलव बिंदु के बाद के अंक काट दिए जाते हैं, इसलिए मान चिह्न चाहे जो हो, शून्य की ओर खिसकता है।
| expression | value |
|---|---|
(int) 3.99 | 3 |
(int) -3.99 | -3 |
7 / 2 | 3 |
(double) 7 / 2 | 3.5 |
(double) (7 / 2) | 3.0 |
7 / 2.0 | 3.5 |
1 + 2.5 | 3.5 |
कास्ट अपने ठीक बाद वाले मान पर लगता है। (double) 7 / 2 पहले 7 को कास्ट करता है, फिर double की तरह भाग देता है; (double) (7 / 2) पहले int भाग करता है और उसके परिणाम 3.0 को कास्ट करता है।
कुछ कोड int को अपने आप double में चौड़ा कर देता है: 1 + 2.5 में, और जब int को double वेरिएबल में संग्रहीत किया जाता है (पृष्ठ 1.2)।
double को निकटतम पूर्णांक में पूर्णांकित करने के लिए उसे शून्य से आधा इकाई दूर खिसकाएँ और फिर ट्रंकेट करें: (int) (x + 0.5) ऋणेतर x के लिए, (int) (x - 0.5) ऋणात्मक x के लिए।
| x | (int) x | rounded |
|---|---|---|
2.7 | 2 | 3 |
-2.7 | -2 | -3 |
3.2 | 3 | 3 |
-1.4 | -1 | -1 |
चित्र इनमें से हर एक को कास्ट करता है: लाल शून्य की ओर ट्रंकेट करता है; नीला आधे से खिसकाता है, फिर ट्रंकेट करता है।
इंटीजर ओवरफ़्लो और राउंड-ऑफ़ त्रुटि
int मेमोरी की एक तय मात्रा, 4 बाइट, में संग्रहीत होता है, इसलिए उसकी एक सीमा होती है: Integer.MIN_VALUE से Integer.MAX_VALUE तक, दोनों शामिल।
| constant | value |
|---|---|
Integer.MAX_VALUE | 2147483647 |
Integer.MIN_VALUE | -2147483648 |
int n = Integer.MAX_VALUE - 2; // n है 2147483645 n = n + 1; // n है 2147483646 n = n + 1; // n है 2147483647 n = n + 1; // n है -2147483648 n = n + 1; // n है -2147483647
यदि कोई एक्सप्रेशन सीमा से बाहर के int में मूल्यांकित होता, तो इंटीजर ओवरफ़्लो होता है। परिणाम सीमा के भीतर का एक int होता है, पर अपेक्षित मान नहीं: MAX_VALUE से एक ऊपर MIN_VALUE है। चित्र int को एक वलय (पैमाने के बिना) के रूप में बनाता है, जिसका जोड़ ऊपर है। कोई त्रुटि संदेश नहीं आता; प्रोग्राम गलत संख्या के साथ आगे बढ़ता रहता है।
double की एक अलग सीमा है। double भी मेमोरी की एक तय मात्रा में संग्रहीत होता है, इसलिए जो परिणाम उसकी क्षमता से अधिक सटीक है, वह उसके द्वारा दर्शाए जा सकने वाले निकटतम मान तक पूर्णांकित हो जाता है: यह राउंड-ऑफ़ त्रुटि है।
System.out.println(0.1 + 0.2); // 0.30000000000000004 न 0.1 का और न 0.2 का सटीक बाइनरी रूप है, और योग में छोटी त्रुटियाँ दिखती हैं। राउंड-ऑफ़ त्रुटि से बचने के लिए जहाँ संभव हो int मान उपयोग करें: पैसे को डॉलर में नहीं, सेंट में गिनें। (इससे बचाने वाले विशेष दशमलव टाइप पाठ्यक्रम से बाहर हैं।)
+=, −=, *=, /=, %=, ++ और −−
कंपाउंड असाइनमेंट ऑपरेटर वेरिएबल के मान और दाईं ओर के मान के बीच अंकगणित करता है, फिर परिणाम को वेरिएबल में असाइन करता है।
score += 5 वही करता है जो score = score + 5 करता है। -=, *=, /= और %= के लिए भी यही सच है; int पर /= पूर्णांक भाग है।
पोस्ट-इन्क्रीमेंट ऑपरेटर ++ संख्यात्मक वेरिएबल में 1 जोड़कर उसे संग्रहीत करता है; पोस्ट-डिक्रीमेंट ऑपरेटर -- 1 घटाता है।
int score = 10; // score है 10 score += 5; // score है 15 score -= 3; // score है 12 score *= 2; // score है 24 score /= 5; // score है 4 score %= 3; // score है 1 score++; // score है 2 score--; // score है 1
चित्र पंक्तियाँ चलाता है और हर मान को एक पट्टी पर रखता है। कागज़ पर भी ऐसे ही ट्रेस करें: एक पंक्ति, एक नया मान।
प्रीफ़िक्स रूप (++x) और अन्य एक्सप्रेशन के भीतर इन्क्रीमेंट (arr[x++]) पाठ्यक्रम से बाहर हैं।
वे क्लास जो आपने नहीं लिखीं, उनका उपयोग
लाइब्रेरी क्लासों का संग्रह है। एप्लिकेशन प्रोग्रामिंग इंटरफ़ेस (API) विनिर्देश प्रोग्रामर को बताता है कि उनका उपयोग कैसे करना है।
क्लास एक रेफ़रेंस टाइप परिभाषित करती है। लाइब्रेरी की क्लासें पैकेज में समूहित होती हैं: String और Math java.lang में हैं, Scanner और ArrayList java.util में। मौजूदा क्लासों से ऑब्जेक्ट उनका कोड देखे बिना बनाए जा सकते हैं; उनका डॉक्यूमेंटेशन ही उन्हें उपयोग के योग्य बनाता है।
क्लास के एट्रिब्यूट उससे संबंधित डेटा हैं, जो वेरिएबलों में संग्रहीत होता है: String के वर्ण। उसके व्यवहार वे हैं जो उसके इंस्टेंस कर सकते हैं, या जो उनके साथ किया जा सकता है, और वे मेथड से परिभाषित होते हैं: length(), substring।
कमेंट कोड को मूल प्रोग्रामर और अन्य लोगों को समझाते हैं। कंपाइलर उन्हें अनदेखा करता है और वे कभी चलाए नहीं जाते। Java में तीन प्रकार हैं:
// a comment to the end of the line /* a block of comment, कई पंक्तियों में */ /** a Javadoc comment, used to make API documentation */
चित्र String को शेल्फ़ से उतारता है और substring का डॉक्यूमेंटेशन खोलता है।
प्रीकंडीशन मेथड चलने से ठीक पहले सही होनी चाहिए, ताकि वह अपेक्षा के अनुसार काम करे। मेथड से इसे जाँचने की अपेक्षा नहीं होती: substring को इस तरह कॉल करना कि to अंत से आगे हो, प्रीकंडीशन तोड़ता है, और परिणाम एक अपवाद होता है, कोई विनम्र उत्तर नहीं।
पोस्टकंडीशन मेथड चलने के बाद हमेशा सही होनी चाहिए। यह परिणाम का वर्णन करती है: क्या लौटाया गया, या उसके बाद ऑब्जेक्ट के एट्रिब्यूट के मान।
पैरामीटर, आर्गुमेंट, रिटर्न वैल्यू
मेथड कोड का एक नामित ब्लॉक है जो केवल कॉल किए जाने पर चलता है। ब्लॉक ब्रेस में लिखा कोई भी कोड है।
प्रोसीजरल एब्स्ट्रैक्शन: आप किसी मेथड का उपयोग यह जानकर कर सकते हैं कि वह क्या करता है, बिना यह जाने कि वह कैसे लिखा गया। उसका हेडर बताता है कि आपको क्या चाहिए:
public static double pow(double base, double exponent)
पैरामीटर हेडर में घोषित वेरिएबल है (base, exponent), जिसका उपयोग मेथड के भीतर होता है। मेथड सिग्नेचर मेथड का नाम और पैरामीटर टाइपों की क्रमबद्ध सूची है: pow(double, double)। बिना पैरामीटर वाले मेथड की सूची खाली होती है: length()।
आर्गुमेंट वह मान है जो मेथड को कॉल करते समय दिया जाता है। आर्गुमेंट संख्या और क्रम में पैरामीटरों से मेल खाने चाहिए। वे मान द्वारा दिए जाते हैं: हर पैरामीटर अपने आर्गुमेंट की प्रति के रूप में शुरू होता है। चित्र में 2 और 10 प्रतियाँ 2.0 और 10.0 बन जाते हैं।
double r = Math.pow(2, 10); System.out.println(r); // 1024.0 non-void मेथड अपने रिटर्न टाइप का मान लौटाता है; उसका उपयोग करने के लिए उसे किसी वेरिएबल में रखें या किसी एक्सप्रेशन में उपयोग करें। void मेथड कुछ नहीं लौटाता, इसलिए वह एक्सप्रेशन का भाग नहीं हो सकता: int x = System.out.println(5); कंपाइल नहीं होता।
मेथड ओवरलोड होते हैं जब कई का नाम एक हो और सिग्नेचर अलग हों: Math.abs(int) और Math.abs(double)। आर्गुमेंट तय करते हैं कि कौन-सा चलेगा।
कॉल स्टेटमेंट के क्रम को बीच में रोक देती है: पहले मेथड के स्टेटमेंट चलते हैं, और जब अंतिम (या return) चल चुका होता है, तो नियंत्रण कॉल के ठीक बाद लौट आता है।
static मेथड, और Math.random()
क्लास मेथड क्लास के होते हैं, किसी एक ऑब्जेक्ट के नहीं। उनके हेडर में कीवर्ड static होता है, और उन्हें क्लास के नाम और डॉट ऑपरेटर से कॉल किया जाता है: Math.sqrt(2.0)। जिस क्लास में वे परिभाषित हैं, उसके भीतर क्लास का नाम छोड़ा जा सकता है।
Math क्लास java.lang में है, इसलिए बिना import के उपलब्ध है, और उसमें केवल क्लास मेथड हैं। Java Quick Reference में पाँच सूचीबद्ध हैं:
| method | returns |
|---|---|
static int abs(int x) | int का निरपेक्ष मान |
static double abs(double x) | double का निरपेक्ष मान |
static double pow(double base, double exponent) | base का exponent घात |
static double sqrt(double x) | ऋणेतर वर्गमूल |
static double random() | एक double जो ≥ 0.0 और < 1.0 हो |
Math.random() की सीमा में 0.0 शामिल है (समावेशी अंतिम बिंदु) और 1.0 शामिल नहीं है (अपवर्जित बिंदु)। अंकगणित और कास्टिंग इसे आपकी मनचाही सीमा में ले आते हैं:
int roll = (int) (Math.random() * 6) + 1;
चित्र इसे चरणों में करता है। * 6 [0.0, 1.0) को [0.0, 6.0) तक फैला देता है। (int) हर भाग को 0, 1, …, 5 तक ट्रंकेट करता है: 6 बराबर भाग, इसलिए 6 समान संभावना वाले मान। + 1 उन्हें 1, …, 6 तक खिसका देता है। सामान्य रूप में, (int) (Math.random() * count) + low count int में से एक देता है, जो low से शुरू होते हैं।
इसके 30 रोल 5 on 1, 5 on 2, 6 on 3, 4 on 4, 6 on 5, 4 on 6 पर आए: समान संभावना का अर्थ यह नहीं कि छोटी श्रृंखला में समान बार आएँ।
ब्लूप्रिंट और वह जो उससे बनता है
क्लास किसी ऑब्जेक्ट के एट्रिब्यूट और व्यवहारों का औपचारिक क्रियान्वयन, यानी ब्लूप्रिंट है। ऑब्जेक्ट क्लास का एक विशिष्ट इंस्टेंस है, जिसके उन एट्रिब्यूट के अपने मान होते हैं।
चित्र एक काल्पनिक क्लास Book का उपयोग करता है, जिसके दो एट्रिब्यूट (शीर्षक और पृष्ठों की संख्या) और दो व्यवहार (getTitle() और getPages()) हैं। उससे बनी हर Book का अपना शीर्षक और पृष्ठ हैं: "नक्शे", 120; "पक्षी", 340; "तारे", 96।
संबंधित क्लासें समान एट्रिब्यूट और व्यवहार एक ही क्लास, सुपरक्लास, में रखकर साझा कर सकती हैं। उसे एक्सटेंड करने वाली क्लासें, सबक्लास, उन एट्रिब्यूट और व्यवहारों को दोबारा लिखे बिना उनका उपयोग करती हैं: यह इनहेरिटेंस संबंध है। (इनहेरिटेंस को डिज़ाइन करना और लिखना पाठ्यक्रम से बाहर है।)
Java की हर क्लास Object क्लास की सबक्लास है, इसीलिए हर ऑब्जेक्ट में toString() और equals जैसे मेथड होते हैं।
रेफ़रेंस टाइप का वेरिएबल ऑब्जेक्ट रेफ़रेंस रखता है, जिसे ऑब्जेक्ट का मेमोरी पता माना जा सकता है: चित्रों में तीर, ऑब्जेक्ट नहीं।
Book b; // b, Book का रेफ़रेंस रख सकता है String s; // s, String का रेफ़रेंस रख सकता है
new, कंस्ट्रक्टर और null
ऑब्जेक्ट कीवर्ड new से बनता है, जिसके बाद क्लास के किसी कंस्ट्रक्टर का कॉल होता है।
कंस्ट्रक्टर का नाम उसकी क्लास के नाम जैसा ही होता है। उसका सिग्नेचर वह नाम और पैरामीटर टाइपों की क्रमबद्ध सूची है; उसका हेडर पैरामीटरों के टाइप और नाम सूचीबद्ध करता है। काल्पनिक Book का डॉक्यूमेंटेशन यह सूचीबद्ध करता है:
Book(String title, int pages) Book(String title) String getTitle() int getPages()
अलग-अलग सिग्नेचर वाले दो कंस्ट्रक्टर: कंस्ट्रक्टर ओवरलोड हैं, और आर्गुमेंट तय करते हैं कि कौन-सा कॉल होगा। new Book("नक्शे") दूसरे को कॉल करता है।
Book b = new Book("नक्शे", 120); Book c = null; चित्र पहली पंक्ति को क्रम से चलाता है: new Book के लिए मेमोरी बनाता है; कंस्ट्रक्टर चलता है, उसके पैरामीटर एट्रिब्यूट के आरंभिक मान तय करते हैं; फिर नए ऑब्जेक्ट का रेफ़रेंस b में संग्रहीत होता है। मेथड कॉल की तरह, कंस्ट्रक्टर कॉल भी स्टेटमेंट के क्रम को बीच में रोकती है, और उसका अंतिम स्टेटमेंट चल जाने पर नियंत्रण कॉल के ठीक बाद लौटता है।
कंस्ट्रक्टर के आर्गुमेंट पैरामीटर टाइपों से संख्या और क्रम में संगत होने चाहिए, और मान द्वारा दिए जाते हैं: new Book(120, "नक्शे") कंपाइल नहीं होता, क्योंकि कोई कंस्ट्रक्टर पहले int और फिर String नहीं लेता।
रेफ़रेंस टाइप का वेरिएबल ऑब्जेक्ट रेफ़रेंस रखता है या, यदि कोई ऑब्जेक्ट नहीं है, तो null: c किसी चीज़ की ओर संकेत नहीं करता।
डॉट ऑपरेटर, और null
इंस्टेंस मेथड क्लास के किसी ऑब्जेक्ट पर कॉल किए जाते हैं, ऑब्जेक्ट के नाम, डॉट ऑपरेटर और मेथड से: b.getPages()।
int p = b.getPages(); // p है 120 int q = c.getPages(); // NullPointerException
कॉल b में रखे रेफ़रेंस का पीछा करके उसके ऑब्जेक्ट तक जाती है, उस ऑब्जेक्ट पर getPages() चलाती है, और जो int लौटता है (120) वह p में संग्रहीत होता है। कोई दूसरा Book ऑब्जेक्ट अपने पृष्ठों के साथ उत्तर देता।
c null है: तीर के पीछे जाने के लिए कोई ऑब्जेक्ट नहीं है। null रेफ़रेंस पर मेथड कॉल करने से पंक्ति चलते समय NullPointerException फेंका जाता है। यह कंपाइल हो जाता है: कंपाइलर केवल यह जाँचता है कि Book में getPages() है।
पृष्ठ 1.10 के क्लास मेथड से तुलना करें: Math.sqrt(x) क्लास पर कॉल होता है; s.length() एक String ऑब्जेक्ट पर कॉल होता है और केवल उसी स्ट्रिंग का उत्तर देता है।
इम्यूटेबल; कॉन्केटनेशन नए बनाता है
String ऑब्जेक्ट वर्णों के क्रम को दर्शाता है। यह स्ट्रिंग लिटरल "cat" से, या कंस्ट्रक्टर new String("cat") से बनता है। String java.lang में है, जो डिफ़ॉल्ट रूप से उपलब्ध है।
String ऑब्जेक्ट इम्यूटेबल है: एक बार बनने के बाद उसके वर्ण कभी नहीं बदलते। String पर कॉल किए गए मेथड उसे नहीं बदलते; वे नया मान लौटाते हैं।
String s = "cat"; // s का मान "cat" है s = s + "s"; // s का मान "cats" है String t = s + 1 + 2; // t का मान "cats12" है String v = 1 + 2 + s; // v का मान "3cats" है
+ और += String को जोड़ते (कॉन्केटनेट करते) हैं, जिससे एक नया String ऑब्जेक्ट बनता है। चित्र में s = s + "s" "cats" बनाता है और s को उसकी ओर कर देता है; "cat" ऑब्जेक्ट अब भी ठीक "cat" ही है।
String के साथ जोड़ा गया प्रिमिटिव String में बदल जाता है। + बाएँ से दाएँ काम करता है, इसलिए यह मायने रखता है कि String पहली बार कहाँ आता है: s + 1 + 2 में हर संख्या टेक्स्ट के रूप में जुड़ती है; 1 + 2 + s में 1 + 2 पहले int की तरह जोड़ा जाता है।
किसी भी ऑब्जेक्ट को String के साथ जोड़ा जा सकता है: Java ऑब्जेक्ट का toString मेथड कॉल करता है, जो हर क्लास को Object से मिलता है और ऑब्जेक्ट को दर्शाने वाली स्ट्रिंग लौटाता है। सबक्लास अक्सर इसे ओवरराइड करती हैं (सुपरक्लास के सिग्नेचर वाला ही एक public मेथड, अपने व्यवहार के साथ); ऐसा ओवरराइड लिखना पाठ्यक्रम से बाहर है।
इंडेक्स, लंबाई, substring, indexOf
String के वर्णों के इंडेक्स 0 से उसकी लंबाई से एक कम तक होते हैं। इस सीमा से बाहर का इंडेक्स उपयोग करने पर StringIndexOutOfBoundsException फेंका जाता है।
Java Quick Reference ये String मेथड सूचीबद्ध करती है (और कंस्ट्रक्टर; split टेक्स्ट फ़ाइलों के साथ आता है, विषय 4.6 में):
| method | returns |
|---|---|
int length() | वर्णों की संख्या |
String substring(int from, int to) | इंडेक्स from से इंडेक्स to - 1 तक के वर्ण |
String substring(int from) | substring(from, length()) |
int indexOf(String str) | str की पहली उपस्थिति का इंडेक्स; न मिले तो −1 |
boolean equals(Object other) | अगला पृष्ठ |
int compareTo(String other) | अगला पृष्ठ |
String s = "BANANAS"; s.length(); // 7 s.substring(1, 4); // "ANA" s.substring(4); // "NAS" s.indexOf("NA"); // 2 s.indexOf("X"); // -1 s.substring(3, 4); // "A"
to वह पहला इंडेक्स है जो छूट जाता है, इसलिए substring(from, to) में to - from वर्ण होते हैं। indexOf केवल पहली उपस्थिति खोजता है: "NA" इंडेक्स 4 पर भी शुरू होता है।
index पर के एकल वर्ण वाली स्ट्रिंग substring(index, index + 1) है।
equals, compareTo, और == नहीं
equals पूछता है कि क्या दो String में वर्णों का एक ही क्रम है। compareTo पूछता है कि कौन पहले आता है।
String a = "pear"; String b = new String("pear"); System.out.println(a == b); // false System.out.println(a.equals(b)); // true System.out.println(a.compareTo("peach") > 0); // true a और b दो अलग ऑब्जेक्ट की ओर संकेत करते हैं जिनमें समान वर्ण हैं। a.equals(b) वर्णों की जोड़ी-दर-जोड़ी तुलना करता है: true। a == b रेफ़रेंस की तुलना करता है, कि क्या वे एक ही ऑब्जेक्ट की ओर संकेत करते हैं: false। String की तुलना equals से करें। (== से रेफ़रेंस की तुलना विषय 2.6 में लौटती है।)
a.compareTo(other) 0 से कम मान लौटाता है यदि a, other से पहले आता है, 0 यदि वे बराबर हैं, और 0 से बड़ा यदि a बाद में आता है। String वर्णमाला के आधार पर क्रमित होती हैं: जहाँ पहली बार वर्ण अलग होते हैं, वही निर्णय करते हैं। "pear" और "peach" इंडेक्स 3 तक एक जैसे हैं, जहाँ 'r', 'c' के बाद आता है, इसलिए परिणाम धनात्मक है। केवल उसके चिह्न पर निर्भर करें: Quick Reference बस इतना ही वादा करती है।
पाठ्यक्रम में equals का उपयोग केवल एक String की दूसरी String से तुलना के लिए होता है।