क्या जावा प्रोग्राम को 'जावा' कमांड संकलित करता है?


145

इंटरनेट पर अधिकांश वेबसाइटें कहती हैं:

" javacकिसी .javaफ़ाइल को संकलित करने के लिए कमांड का उपयोग करें । फिर javaकमांड का उपयोग करके इसे चलाएं "

लेकिन आज मैंने बिना जावा प्रोग्राम चलाने की कोशिश की javacऔर मुझे एक अजीब परिणाम मिला।

यहाँ एक फ़ाइल की सामग्री को कहा जाता है hello.java:

public class Myclass {
 public static void main(String[] args){
    System.out.println("hello world");
  }
}

फिर मैं भागा:

$ javac hello.java

जो मुझे यह त्रुटि देता है:

hello.java:1: error: class Myclass is public, should be declared in a file named Myclass.java
public class Myclass {
       ^
1 error

लेकिन जब मैं इसे javacकमांड के बिना चलाता हूं , तो यह बिना किसी त्रुटि के निष्पादित होता है।

$ java hello.java
hello world

क्या javaकमांड भी प्रोग्राम को संकलित करता है? यदि हाँ, तो हमें javacकमांड की आवश्यकता क्यों है ?

मेरे जावा का संस्करण है:

openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)

11
आपके द्वारा कौन सा संस्करण उपयोग किया जा रहा है? मुझे लगता है कि उन्होंने जावा 9 में जावा कंसोल की शुरुआत की, और यह वही हो सकता है जो आपने अनुभव किया है।
मथिउव

6
आपको इसके नाम के साथ वर्ग के नाम का मिलान करने की आवश्यकता है - यह जावा मानक है। बस फ़ाइल का नाम बदलकर Myclass.javaकमांड लाइन से इसे इस तरह संकलित करें javac Myclass.javaऔर फिर इसे इस तरह चलाएं java Myclass
बजे

6
हाँ, javacयदि आप स्रोत कोड को तैनात नहीं करना चाहते हैं , तब भी संकलित करने के लिए उपयोग किया जाता है, या आपके पास एक से अधिक फ़ाइल ( स्रोत-फ़ाइल विकल्प के लिए दस्तावेज़ीकरणjava : केवल एक स्रोत-फ़ाइल प्रोग्राम लॉन्च करने के लिए उपयोग किया जाता है।)
user85421

@ मैथ्यू "" जावा-वर्जन "का आउटपुट है: ओपनजडक संस्करण" 12.0.2 "2019-07-16 ओपनजेडके रनटाइम एनवायरनमेंट (बिल्ड 12.0.2 + 10) ओपनजेडके 64-बिट सर्वर वीएम (12.0.2 + 10 का निर्माण, मिश्रित) मोड)
दूधिया

1
@ मीलाद - यह क्या होता है - javacजावा स्रोत को JVM द्वारा व्याख्या किए गए विशिष्ट बायोटेक में संकलित किया गया है और javaकमांड इसे JVM के क्लासलोडर के अंदर लोड करता है।
18

जवाबों:


188

जावा 11 से पहले, अपने कोड को चलाने के लिए आपको पहले इसे संकलित करना होगा, फिर आप इसे चला सकते हैं। यहाँ एक उदाहरण है:

javac test.java
java test

जावा 11 के बाद से, आप अभी भी javac+ javaकर सकते हैं, या आप javaअपने कोड को संकलित करने और ऑटो चलाने के लिए खुद से चला सकते हैं। ध्यान दें कि कोई .classफ़ाइल उत्पन्न नहीं होगी। यहाँ एक उदाहरण है:

java test.java

यदि आप दौड़ते हैं java -help, तो आप विभिन्न अनुमत उपयोगों को देखेंगे। यहाँ यह मेरी मशीन पर कैसा दिखता है। पिछले एक वह है जो आप में भाग गए: java [options] <sourcefile> [args]जो "एकल स्रोत-फ़ाइल प्रोग्राम को निष्पादित करेगा"।

$ java -help
Usage: java [options] <mainclass> [args...]
           (to execute a class)
   or  java [options] -jar <jarfile> [args...]
           (to execute a jar file)
   or  java [options] -m <module>[/<mainclass>] [args...]
       java [options] --module <module>[/<mainclass>] [args...]
           (to execute the main class in a module)
   or  java [options] <sourcefile> [args]
           (to execute a single source-file program)

अपडेट करें:

जैसा कि @BillK ने बताया, ओपी ने यह भी पूछा:

हमें javac कमांड की आवश्यकता क्यों है?

कारण हमें फ़ाइलों javacको बनाने की आवश्यकता है .classताकि कोड बनाया जा सके, परीक्षण किया जा सके, वितरित किया जा सके, चलाया जा सके, साझा किया जा सके, जैसे कि यह आज है। जेईपी 330 के लिए प्रेरणा "जावा सीखने के शुरुआती चरणों के लिए, और किसी भी मौजूदा उपयोग को बदलने के बिना छोटे उपयोगिता कार्यक्रम लिखते समय" को आसान बनाना था ।



अतिरिक्त विवरण के लिए @CarlosHeuberger धन्यवाद। मैंने अपने उत्तर में यह दर्शाने के लिए एक छोटा-सा संपादन किया कि यह जावा 11 में प्रस्तुत किया गया था
kanan

7
@Spikatrix जावा 8 है कि (वे गिरा 1.में 1.8नए विज्ञप्ति में)
muru

1
आपने इस प्रश्न का उत्तर नहीं दिया कि हमें अभी भी javac की आवश्यकता क्यों है - मुझे लगता है कि java केवल उस एकल फ़ाइल पर काम करता है जिसे आप इसकी आपूर्ति करते हैं और पहले संकलित फ़ाइलें। मेरा मानना ​​है कि आपको अपने द्वारा कॉल की जाने वाली फ़ाइल से उपयोग करने की इच्छा रखने वाली अन्य सभी फ़ाइलों को संकलित करना होगा।
बिल के

2
यह उत्तर यह नहीं बताता है कि यह नई विधि फ़ाइल नाम बनाम वर्ग नाम त्रुटि के कारण परिणाम नहीं देती है javac
सेब्रोकम

52

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

यदि आप जावा के पिछले संस्करण पर हैं, तो आपका वर्तमान हेल्लो.जावा संकलित त्रुटियों के कारण, विशेष रूप से वर्ग नाम के आसपास, संकलन नहीं करता है। तो वहाँ बिल्कुल कोई रास्ता नहीं है कि java hello.java कॉलिंग ने आपके कोड को संकलित किया, क्योंकि यह संकलन नहीं करता है।

यह पूरी तरह से संभावना है कि आप जावा कमांड को निष्पादित करते समय कुछ पहले संकलित कोड चला रहे थे।


धन्यवाद, जावा संस्करण है: openjdk संस्करण "12.0.2" 2019/07/16 OpenJDK रनटाइम वातावरण (निर्माण 12.0.2 + 10) OpenJDK 64-बिट सर्वर वी एम (निर्माण 12.0.2 + 10, मिश्रित मोड)
मिलाद

5
सिंगल-फाइल सोर्स-कोड प्रोग्राम लॉन्च करने के लिए सोर्स-फाइल मोड का उपयोग करके जांच करें : "कंपाइलर जेएलएस ?? 7.6 के अंत में परिभाषित वैकल्पिक प्रतिबंध को लागू नहीं करता है, कि एक नामित पैकेज में एक प्रकार एक फ़ाइल में मौजूद होना चाहिए जिसका नाम है ".java एक्सटेंशन के बाद टाइप नाम से बना है।"
user85421

2
जावा स्क्रिप्टिंग एपीआई और जावा सिंगल-फाइल सोर्स-कोड प्रोग्राम लॉन्च ( जेईपी 330 ) दो पूरी तरह से अलग और पूरी तरह से असंबंधित चीजें हैं।
डेविड कॉनरेड

@DavidConrad, तदनुसार अद्यतन किया गया। धन्यवाद।
इवान

इनपुट की सराहना करें, @TJCrowder। लेकिन, मुझे पूरा यकीन है कि मैं इसे लिखने का मतलब है। इसके अलावा, आपके लिंक में दूसरी परिभाषा: विभिन्न चीजों की एक विस्तृत श्रृंखला सहित प्रमुख साधन।
इवान

6

यह उत्तर देने के लिए कि यह त्रुटि क्यों दी गई है, फ़ाइल के लिए कक्षा का नाम फ़ाइल से मेल खाना चाहिए basename

आपके पास पारंपरिक के लिए इस कोड का काम करने के लिए दो विकल्प हैं javac; javaअनुक्रम:

  1. वर्ग का नाम बदलें public class Helloया

  2. नाम बदलें hello.javaकरने के लिए myclass.java

javaजावा 11 के लिए दुभाषिया इस आवश्यकता को लागू नहीं करता। वह वर्ग जिसमें mainकोई भी नाम हो सकता है, जब तक कि वह फ़ाइल में प्रथम श्रेणी है। यह मुख्य रूप से शुरुआती लोगों के लिए सीखने की प्रक्रिया को आसान बनाने के लिए, और शेबंग ( रेफरी ) के साथ "जावा स्क्रिप्टिंग" की अनुमति देने के लिए किया गया था ।


5

हां, लेकिन उस तरीके से नहीं जैसा कि आप शायद कहते हैं।

जब आप javac.java फ़ाइल को एक .class फ़ाइल में संकलित करने के लिए कमांड का उपयोग करते हैं, तो आउटपुट कुछ बायटेकोड कहलाता है। बाइटकोड एक जावा वर्चुअल मशीन विनिर्देश के आधार पर एक सैद्धांतिक सीपीयू के लिए मशीन कोड (मूल निर्देश) है।

यह वर्चुअल CPU विनिर्देश एक प्रकार का CPU है जो विनिर्देशन लिखे जाने के समय सामान्य था। इस वजह से यह बहुत से विभिन्न प्रकार के सीपीयू के करीब है जो एक ही जावा .class फ़ाइलों को कई CPU प्रकारों पर चलाना आसान बनाता है।

जब जावा को पहली बार लॉन्च किया गया था, तो javaकमांड .class फ़ाइल को पढ़ेगा और एक बार में बायटेकोड निर्देशों की व्याख्या करेगा और फिर उन्हें वास्तव में चल रहे सीपीयू के समतुल्य मूल अनुदेश के लिए मैप करेगा। यह काम किया लेकिन विशेष रूप से तेज नहीं था। इसे जस्ट टू टाइम (JIT) संकलन में सुधार के लिए जावा रनटाइम में जोड़ा गया था।

JIT के साथ javaकमांड बाईटेकोड लेता है और इसे फिर से सीपीयू के मूल निर्देशों के लिए संकलित करता है। आधुनिक जावा रनटाइम्स बायटेकोड की व्याख्या करना शुरू कर देते हैं, जबकि JIT पृष्ठभूमि में संकलन करता है और संकलित देशी निर्देशों पर स्विच करता है जब यह तैयार होता है और यह रनिंग एप्लिकेशन को भी प्रोफाइल करेगा और फिर सर्वोत्तम संभव प्रदर्शन प्राप्त करने के लिए अलग-अलग अनुकूलन के साथ फिर से बायटेकोड को फिर से जोड़ देगा।

EDIT (मतदाताओं को खुश करने के लिए):

तो आपके विशिष्ट मामले में (जैसा कि आप v11 से नया JRE चला रहे हैं) कोड दो बार (कम से कम) संकलित किया गया है

  1. एक एकल .java फ़ाइल के रूप में बाइटकोड के लिए
  2. जेआईटी संकलक के रूप में यह बाईटेकोड की व्याख्या करता है (हालांकि हैलोवर्ल्ड के लिए यह वास्तव में संकलित मूल कोड को चलाने का समय नहीं मिल सकता है)

7
इस सवाल का जवाब नहीं है।
डेविड कॉनरेड

2
@DavidConrad लेकिन यह करता है! "जावा" कमांड जावा प्रोग्राम को संकलित करता है? हार्डलिब यहां दिए गए कारणों के लिए एक शानदार "हां" है: यह मूल निर्देशों के लिए बाइट कोड को सिर्फ-इन-टाइम (गैर-तुच्छ कार्यक्रमों के लिए, मानक सेटिंग्स के साथ) संकलित करेगा।
पीटर -

क्या अब संकलन अनिवार्य है? ऐतिहासिक रूप से जावा बाइट कोड की व्याख्या की जा सकती है; JIT संकलन वैकल्पिक था।
MSALERS

JIT इन दिनों डिफ़ॉल्ट रूप से है (बहुत लंबे समय के लिए), जैसा mixed-modeकि संस्करण आउटपुट में दिखाया गया है
hardillb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.