java - जावा मुख्य विधि स्थिर क्यों है?




static main (20)

जावा मुख्य () विधि का विधि हस्ताक्षर है:

public static void main(String[] args){
    ...
}

क्या इस विधि के लिए स्थैतिक होने का कोई कारण है?


The public static void keywords mean the Java virtual machine (JVM) interpreter can call the program's main method to start the program (public) without creating an instance of the class (static), and the program does not return data to the Java VM interpreter (void) when it ends.

Source: Essentials, Part 1, Lesson 2: Building Applications


क्यों सार्वजनिक स्थैतिक शून्य मुख्य (स्ट्रिंग [] तर्क)?

इस प्रकार जावा भाषा डिज़ाइन की गई है और जावा वर्चुअल मशीन डिज़ाइन और लिखी गई है।

ओरेकल जावा भाषा विशिष्टता

अध्याय 12 निष्पादन देखें - खंड 12.1.4 परीक्षा आमंत्रित करें। मुख्य :

अंत में, कक्षा परीक्षण के लिए प्रारंभिक समापन के बाद (जिसके दौरान अन्य परिणामी लोडिंग, लिंकिंग और प्रारंभिक घटनाएं हो सकती हैं), टेस्ट का मुख्य तरीका लागू किया जाता है।

मुख्य विधि को सार्वजनिक, स्थैतिक और शून्य घोषित किया जाना चाहिए। इसे एक भी तर्क स्वीकार करना चाहिए जो तारों की एक सरणी है। इस विधि को या तो घोषित किया जा सकता है

public static void main(String[] args)

या

public static void main(String... args)

ओरेकल जावा वर्चुअल मशीन विशिष्टता

अध्याय 2 जावा प्रोग्रामिंग भाषा अवधारणाओं की जांच करें - खंड 2.17 निष्पादन :

जावा आभासी मशीन कुछ निर्दिष्ट वर्ग के विधि मुख्य का आह्वान करके निष्पादन शुरू करती है और इसे एक एकल तर्क पास करती है, जो तारों की एक सरणी है। इससे निर्दिष्ट वर्ग को लोड किया जा सकता है (§2.17.2), लिंक (§2.17.3) अन्य प्रकारों से जुड़ा हुआ है, और प्रारंभ (§2.17.4)। मुख्य विधि को सार्वजनिक, स्थैतिक और शून्य घोषित किया जाना चाहिए।

ओरेकल ओपनजेडीके स्रोत

स्रोत जार को डाउनलोड और निकालें और देखें कि JVM कैसे लिखा गया है, ../launcher/java.c , जिसमें कमांड java [-options] class [args...] के पीछे मूल सी कोड शामिल है:

/*
 * Get the application's main class.
 * ... ...
 */
if (jarfile != 0) {
    mainClassName = GetMainClassName(env, jarfile);

... ...

    mainClass = LoadClass(env, classname);
    if(mainClass == NULL) { /* exception occured */

... ...

/* Get the application's main method */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
                                   "([Ljava/lang/String;)V");

... ...

{    /* Make sure the main method is public */
    jint mods;
    jmethodID mid;
    jobject obj = (*env)->ToReflectedMethod(env, mainClass,
                                            mainID, JNI_TRUE);

... ...

/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
    ReportExceptionDescription(env);
    goto leave;
}

/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

... ...

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


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

इसके साथ-साथ, मैं निम्नलिखित तीन विकल्पों में से एक को चुनने के लिए तर्क की जांच करूंगा:

  1. एक static void main() जैसा कि हम आज देखते हैं।
  2. एक उदाहरण विधि void main() को ताजा निर्मित वस्तु पर बुलाया जाता है।
  3. प्रवेश बिंदु के रूप में किसी प्रकार के निर्माता का उपयोग करना (उदाहरण के लिए, यदि प्रवेश वर्ग को Program कहा जाता है, तो निष्पादन प्रभावी रूप से new Program() ) से प्रभावी होगा।

टूट - फूट:

static void main()

  1. संलग्न वर्ग के स्थिर कन्स्ट्रक्टर को कॉल करता है।
  2. स्थिर विधि main() कॉल करता है।

void main()

  1. संलग्न वर्ग के स्थिर कन्स्ट्रक्टर को कॉल करता है।
  2. प्रभावी रूप से new ClassName() कॉल करके संलग्न कक्षा का एक उदाहरण तैयार करता है।
  3. main() विधि कॉल main()

new ClassName()

  1. संलग्न वर्ग के स्थिर कन्स्ट्रक्टर को कॉल करता है।
  2. कक्षा का एक उदाहरण बनाता है (फिर इसके साथ कुछ भी नहीं करता है और बस लौटाता है)।

दलील:

मैं इस के लिए रिवर्स ऑर्डर में जाऊंगा।

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

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

संक्षेप में, एक static void main() निर्दिष्ट करना कम से कम जटिलता के साथ एक विनिर्देश बनाता है जबकि तरीकों में व्यवहार रखने के सिद्धांत का पालन करते हैं । यह ध्यान में रखते हुए कि एक main() विधि को कार्यान्वित करना कितना सरल है, जो स्वयं एक वर्ग का उदाहरण बनाता है और एक आवृत्ति विधि कहता है, main() विधि को एक उदाहरण विधि के रूप में निर्दिष्ट करने का कोई वास्तविक लाभ नहीं है।


जब आप java कमांड के साथ जावा वर्चुअल मशीन (JVM) निष्पादित करते हैं,

java ClassName argument1 argument2 ...

जब आप अपना आवेदन निष्पादित करते हैं, तो आप ऊपर दिए गए जावा कमांड के लिए तर्क के रूप में अपना वर्ग नाम निर्दिष्ट करते हैं

JVM आपके द्वारा निर्दिष्ट कक्षा के मुख्य विधि का आह्वान करने का प्रयास करता है

इस बिंदु पर, वर्ग की कोई वस्तु नहीं बनाई गई है।

स्थिर के रूप में main घोषित करने से कक्षा के instance के without जेवीएम main रूप से आक्रमण करने की allows है।

आइए कमांड पर वापस आइए

ClassName जेवीएम के लिए एक command-line argument है जो बताता है कि कौन सा वर्ग निष्पादित करना है। क्लासनाम के बाद, आप list of Strings (रिक्त स्थान से अलग) list of Strings भी कमांड लाइन तर्क के रूप में निर्दिष्ट कर सकते हैं कि JVM आपके एप्लिकेशन को पास कर देगा। - एप्लिकेशन को चलाने के लिए विकल्पों को निर्दिष्ट करने के लिए बहुत से तर्कों का उपयोग किया जा सकता है (उदाहरण के लिए, एक फ़ाइल नाम )- यही कारण है कि मुख्य में String[] args तर्क नामक पैरामीटर है

संदर्भ: जावा ™ प्रोग्राम कैसे करें (प्रारंभिक ऑब्जेक्ट्स), दसवां संस्करण


प्रोटोटाइप public static void main(String[]) JLS में परिभाषित एक सम्मेलन है:

मुख्य विधि को सार्वजनिक, स्थैतिक और शून्य घोषित किया जाना चाहिए। इसे औपचारिक पैरामीटर (§8.4.1) निर्दिष्ट करना होगा जिसका घोषित प्रकार स्ट्रिंग का सरणी है।

जेवीएम विनिर्देश 5.2 में। वर्चुअल मशीन स्टार्ट-अप हम पढ़ सकते हैं:

जावा वर्चुअल मशीन प्रारंभिक कक्षा बनाकर शुरू होती है, जिसे बूटस्ट्रैप क्लास लोडर (§5.3.1) का उपयोग करके कार्यान्वयन-निर्भर तरीके से निर्दिष्ट किया जाता है। जावा आभासी मशीन तब प्रारंभिक वर्ग को जोड़ती है, इसे प्रारंभ करती है, और सार्वजनिक वर्ग विधि शून्य मुख्य (स्ट्रिंग []) को आमंत्रित करती है । इस विधि का आविष्कार सभी आगे निष्पादन चलाता है। मुख्य विधि का गठन करने वाले जावा वर्चुअल मशीन निर्देशों का निष्पादन अतिरिक्त वर्गों और इंटरफेस के लिंकिंग (और इसके परिणामस्वरूप सृजन) का कारण बन सकता है, साथ ही साथ अतिरिक्त विधियों का आविष्कार भी हो सकता है।

मजेदार बात, जेवीएम विनिर्देश में यह उल्लेख नहीं है कि मुख्य विधि स्थिर होना चाहिए। लेकिन कल्पना यह भी कहती है कि जावा आभासी मशीन पहले 2 कदम करती है:

किसी वर्ग या इंटरफ़ेस की शुरुआत में इसकी कक्षा या इंटरफ़ेस प्रारंभिक विधि निष्पादित होती है।

2.9 में विशेष तरीके :

एक कक्षा या इंटरफ़ेस प्रारंभिक विधि परिभाषित की गई है:

एक वर्ग या इंटरफ़ेस में अधिकांश एक वर्ग या इंटरफ़ेस प्रारंभिक विधि होती है और उस विधि को आविष्कार करके प्रारंभ किया जाता है (§5.5)। किसी वर्ग या इंटरफ़ेस की आरंभिक विधि का विशेष नाम <clinit> , कोई तर्क नहीं लेता है, और शून्य है।

और एक वर्ग या इंटरफ़ेस प्रारंभिक विधि निम्न उदाहरण के रूप में परिभाषित एक प्रारंभिक प्रारंभिक विधि से अलग है:

जावा वर्चुअल मशीन के स्तर पर, जावा प्रोग्रामिंग भाषा (जेएलएस §8.8) में लिखे गए प्रत्येक कन्स्ट्रक्टर एक उदाहरण प्रारंभिक विधि के रूप में प्रकट होता है जिसमें विशेष नाम <init>

तो JVM एक वर्ग या इंटरफ़ेस प्रारंभिक विधि प्रारंभ करता है और एक उदाहरण प्रारंभिक विधि नहीं है जो वास्तव में एक निर्माता है। इसलिए उन्हें यह उल्लेख करने की आवश्यकता नहीं है कि मुख्य विधि को JVM spec में स्थिर होना चाहिए क्योंकि यह इस तथ्य से निहित है कि मुख्य विधि को कॉल करने से पहले कोई उदाहरण नहीं बनाया गया है।


मुख्य विधि कहने से पहले, कोई वस्तु तत्काल नहीं होती है। स्थैतिक कीवर्ड होने का मतलब है कि किसी भी वस्तु को पहले बनाए बिना विधि को बुलाया जा सकता है।


मुझे इन चीजों को एक बहुत ही सरल तरीके से समझाएं:

public static void main(String args[])

एप्लेट को छोड़कर सभी जावा एप्लिकेशन, main() से अपना निष्पादन शुरू करते हैं।

कीवर्ड public एक एक्सेस संशोधक है जो सदस्य को वर्ग के बाहर से कॉल करने की अनुमति देता है।

static का उपयोग किया जाता है क्योंकि यह उस वर्ग के किसी विशेष उदाहरण को तत्काल करने के बिना main() को कॉल करने की अनुमति देता है।

void इंगित करता है कि main() कोई मूल्य वापस नहीं करता है।


यदि मुख्य विधि स्थैतिक नहीं होगी, तो आपको प्रोग्राम के बाहर से अपनी मुख्य कक्षा का ऑब्जेक्ट बनाना होगा। आप यह कैसे करना चाहते हैं?


यदि यह नहीं था, तो एक से अधिक होने पर कौन सा कन्स्ट्रक्टर इस्तेमाल किया जाना चाहिए?

जावा भाषा विशिष्टता में उपलब्ध जावा प्रोग्राम के आरंभ और निष्पादन के बारे में अधिक जानकारी है।


यह सिर्फ एक सम्मेलन है। जेवीएम निश्चित रूप से गैर स्थैतिक मुख्य तरीकों से निपट सकता है अगर वह सम्मेलन होता। आखिरकार, आप अपनी कक्षा में एक स्थिर प्रारंभकर्ता को परिभाषित कर सकते हैं, और अपनी मुख्य () विधि को प्राप्त करने से पहले एक अरब वस्तुओं को तुरंत चालू कर सकते हैं।


यह सिर्फ सम्मेलन है। वास्तव में, यहां तक ​​कि नाम मुख्य (), और पारित तर्क पूरी तरह से सम्मेलन हैं।

जब आप java.exe (या Windows पर javaw.exe) चलाते हैं, तो वास्तव में क्या हो रहा है जावा नेटिव इंटरफेस (जेएनआई) कॉल के कुछ जोड़े हैं। ये कॉल DLL लोड करते हैं जो वास्तव में JVM है (यह सही है - java.exe JVM नहीं है)। जेएनआई वह उपकरण है जिसका उपयोग हम वर्चुअल मशीन दुनिया और सी, सी ++, आदि की दुनिया के बीच पुल करना चाहते हैं ... रिवर्स भी सच है - वास्तव में संभव नहीं है (कम से कम मेरे ज्ञान के लिए) जेएनआई का उपयोग किये बिना एक जेवीएम चल रहा है।

असल में, java.exe एक सुपर सरल सी अनुप्रयोग है जो कमांड लाइन को पार करता है, उन तर्कों को पकड़ने के लिए JVM में एक नई स्ट्रिंग सरणी बनाता है, जिसे क्लास नाम से बाहर रखा गया है जिसे आपने मुख्य () के रूप में निर्दिष्ट किया है, जेएनआई कॉल का उपयोग करता है मुख्य () विधि स्वयं, फिर पैरामीटर के रूप में नव निर्मित स्ट्रिंग सरणी में गुजरने वाली मुख्य () विधि को आमंत्रित करती है। यह बहुत ही है, जब आप जावा से प्रतिबिंब का उपयोग करते हैं तो आप बहुत कुछ करते हैं - यह केवल भ्रमित रूप से नामित देशी फ़ंक्शन कॉल का उपयोग करता है।

Java.exe का अपना संस्करण लिखने के लिए यह पूरी तरह कानूनी होगा (स्रोत जेडीके के साथ वितरित किया जाता है), और यह कुछ पूरी तरह से अलग है। असल में, यह वही है जो हम अपने सभी जावा आधारित ऐप्स के साथ करते हैं।

हमारे प्रत्येक जावा ऐप्स में अपना लॉन्चर होता है। हम मुख्य रूप से ऐसा करते हैं इसलिए हमें अपना स्वयं का आइकन और प्रक्रिया का नाम मिलता है, लेकिन यह अन्य परिस्थितियों में आसान हो गया है जहां हम चीजों को पाने के लिए नियमित मुख्य () कॉल के अलावा कुछ करना चाहते हैं (उदाहरण के लिए, एक मामले में हम कर रहे हैं COM इंटरऑपरेबिलिटी, और हम वास्तव में एक स्ट्रिंग सरणी के बजाय मुख्य () में एक COM हैंडल पास करते हैं)।

तो, लंबा और छोटा: कारण स्थिर है बी / सी यह सुविधाजनक है। इसका कारण 'मुख्य' कहा जाता है क्योंकि यह कुछ होना था, और मुख्य () वह है जो उन्होंने सी के पुराने दिनों में किया था (और उन दिनों में, समारोह का नाम महत्वपूर्ण था )। मुझे लगता है कि java.exe आपको केवल कक्षा (जावा com.mycompany.Foo.someSpecialMain) की बजाय पूरी तरह से योग्य मुख्य विधि नाम निर्दिष्ट करने की अनुमति दे सकता था - लेकिन यह आईडीई पर इसे ' प्रोजेक्ट में लॉन्च करने योग्य 'कक्षाएं।


सी ++, सी # और जावा में मुख्य () विधि स्थैतिक हैं क्योंकि उन्हें रनटाइम इंजन द्वारा अभिभावक वर्ग के उदाहरण को तत्काल किए बिना बुलाया जा सकता है।


हाल ही में, प्रोग्रामर.एसई पर इसी तरह का सवाल पोस्ट किया गया है

  • एक कन्स्ट्रक्टर की बजाय जावा और सी # में एक स्थिर मुख्य विधि क्यों?

    प्राथमिक या द्वितीयक स्रोत से एक निश्चित उत्तर की तलाश में क्यों (विशेष रूप से) जावा और सी # ने प्रवेश बिंदु के साथ एक Application वर्ग के उदाहरण द्वारा अनुप्रयोग आवृत्ति का प्रतिनिधित्व करने के बजाय एक स्थाई विधि के रूप में एक स्थिर विधि तय करने का निर्णय लिया एक उपयुक्त निर्माता?

TL;DR स्वीकृत उत्तर का TL;DR हिस्सा है,

जावा में, public static void main(String[] args) तर्क public static void main(String[] args) कारण यह है

  1. Gosling चाहता था
  2. सी में अनुभवी किसी व्यक्ति द्वारा लिखित कोड (जावा में नहीं)
  3. NeWS पर PostScript चलाने के लिए प्रयुक्त किसी व्यक्ति द्वारा निष्पादित किया NeWS


सी # के लिए, तर्क बोलने के लिए समान रूप से समान है। भाषा डिजाइनरों ने जावा से आने वाले प्रोग्रामर के लिए परिचित प्रोग्राम एंट्री पॉइंट सिंटैक्स रखा। सी # आर्किटेक्ट एंडर्स हेजल्सबर्ग ने इसे रखा है ,

... सी # के साथ हमारा दृष्टिकोण बस एक प्रोग्राम प्रदान करने के लिए किया गया है ... जावा प्रोग्रामर के लिए ...

...


Any method declared as static in Java belongs to the class itself . Again static method of a particular class can be accessed only by referring to the class like Class_name.method_name();

So a class need not to be instantiated before accessing a static method.

So the main() method is declared as static so that it can be accessed without creating an object of that class.

Since we save the program with the name of the class where the main method is present( or from where the program should begin its execution, applicable for classes without a main() method()(Advanced Level)). So by the above mentioned way:

Class_name.method_name();

the main method can be accessed.

In brief when the program is compiled it searches for the main() method having String arguments like: main(String args[]) in the class mentioned(ie by the name of the program), and since at the the beginning it has no scope to instantiate that class, so the main() method is declared as static.


Basically we make those DATA MEMBERS and MEMBER FUNCTIONS as STATIC which are not performing any task related to an object. And in case of main method, we are making it as an STATIC because it is nothing to do with object, as the main method always run whether we are creating an object or not.


It is just a convention as we can see here:

The method must be declared public and static , it must not return any value, and it must accept a String array as a parameter. By default, the first non-option argument is the name of the class to be invoked. A fully-qualified class name should be used. If the -jar option is specified, the first non-option argument is the name of a JAR archive containing class and resource files for the application, with the startup class indicated by the Main-Class manifest header.

http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html#description


Static methods don't require any object. It runs directly so main runs directly.


The static key word in the main method is used because there isn't any instantiation that take place in the main method. But object is constructed rather than invocation as a result we use the static key word in the main method. In jvm context memory is created when class loads into it.And all static members are present in that memory. if we make the main static now it will be in memory and can be accessible to jvm (class.main(..)) so we can call the main method with out need of even need for heap been created.


static - When the JVM makes a call to the main method there is no object that exists for the class being called therefore it has to have static method to allow invocation from class.





main