2013-02-23 10 views
7

जेएलएस के मुताबिक: यह एक संकलित-समय त्रुटि है यदि एक आवृत्ति चर प्रारंभकर्ता या नामित वर्ग का इंस्टेंस प्रारंभकर्ता एक अपवाद वर्ग को फेंक सकता है, जब तक कि अपवाद वर्ग या उसके सुपरक्लास को स्पष्ट रूप से घोषित नहीं किया जाता अपनी कक्षा के प्रत्येक कन्स्ट्रक्टर के फेंकने वाले खंड में और कक्षा में कम से कम एक स्पष्ट रूप से घोषित कन्स्ट्रक्टर है।चेक अपवाद और प्रारंभकर्ता ब्लॉक

मैं करता हूँ तो अगर इस -

class A{ 
{ 
    throw new FileNotFoundException(); 
} 
public A() throws IOException{ 
    // TODO Auto-generated constructor stub 
} 
} 

यह एक संकलन समय त्रुटि देता है "प्रारंभकर्ता सामान्य रूप से पूरा करना होगा"

जबकि

class A{ 
{ 
    File f=new File("a"); 
    FileOutputStream fo=new FileOutputStream(f); 
    fo.write(3); 
} 
public A() throws IOException{ 
    // TODO Auto-generated constructor stub 
} 
} 

इस कोड को किसी भी संकलन समय प्रदर्शित नहीं करता है त्रुटि। पिछला कोड संकलित क्यों नहीं करता है भले ही मैंने कन्स्ट्रक्टर में थ्रो क्लॉज घोषित किया हो?

+0

आपने बिना शर्त अपवाद को फेंकने के लिए प्रारंभकर्ता ब्लॉक को बताया, आप और क्या उम्मीद करेंगे? – skuntsel

उत्तर

4

कुछ ऐसी स्थिति होनी चाहिए जब प्रारंभकर्ता वास्तव में किसी भी अपवाद के बिना पूरा कर सके।

आपके मामले में ऐसा कोई तरीका नहीं है कि यह हो सकता है।

प्रयास करें:

if(/*condition-to-fail*/) { 
    /*Not always, only when something is wrong. Compiler knows that.*/ 
    throw new FileNotFoundException(); 
} 

अद्यतन:

निम्नलिखित बयान वास्तव में अपवाद फेंक रहा है।

throw new FileNotFoundException(); 

इसलिए कोई शर्त नहीं है कि आपका प्रोग्राम निष्पादन हमेशा समाप्त होता है।

जबकि निम्नलिखित में

-

FileOutputStream fo = new FileOutputStream(f); 

निर्माता FileOutputStream(File) हमेशा कि अपवाद फेंक नहीं है।

public FileOutputStream(File file) throws FileNotFoundException में फेंकता खंड केवल यह कह रहा है कि यह उस अपवाद को फेंक सकता है, और यह केवल तभी होगा जब रनटाइम पर फ़ाइल अन्यथा नहीं मिलती है।

+0

+1 जो काम करता है। लेकिन हमें एक सशर्त बयान क्यों चाहिए ?? अपवाद कार्य को फेंक नहीं सकता ?? – PermGenError

+2

@PremGenError: यह किसी भी स्थिति की जांच के बिना रिटर्न स्टेटमेंट के बाद कोड लिखने जैसा है। कंपाइलर भी इस मामले में इसका पता लगा सकता है। –

+0

अच्छा ... धन्यवाद :) – PermGenError

2

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.6

It is a compile-time error if an instance initializer cannot complete normally

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

A non-empty block that is not a switch block can complete normally iff the last statement in it can complete normally.

...

The if statement, whether or not it has an else part, is handled in an unusual manner. For this reason, it is discussed separately at the end of this section.

...

in order to allow the if statement to be used conveniently for "conditional compilation" purposes, the actual rules differ.

...

+0

+1 केवल उत्तर जो वास्तविक कारण देता है। – assylias

1

पहले प्रकरण संकलक में पहले से ही जानते हुए भी कि उदाहरण प्रारंभकर्ता कभी नहीं सामान्य रूप से पूरा करने के लिए है क्योंकि आप स्पष्ट रूप से वहाँ पर FileNotFoundException फेंक दिया है जा रहा है है। आप इसे कंपाइलर का स्मार्ट कोड मूल्यांकन कह सकते हैं। लेकिन यदि आप यह मानने के लिए कंपाइलर बनाते हैं कि इंस्टेंस प्रारंभकर्ता को सफलतापूर्वक पूरा करने का थोड़ा सा मौका भी है तो संकलन के दौरान संकलक शिकायत नहीं करेगा। उदाहरण के लिए नीचे दिए गए कोड में हालांकि फ़ाइल IDonotexist.txt मेरी निर्देशिका पर मौजूद नहीं है और मुझे यकीन है कि यह FileNotFoundException फेंक देगा लेकिन फिर भी कंपाइलर इसे सफलतापूर्वक संकलित करने देगा। क्यों? क्योंकि फाइल के अस्तित्व को कोड के निष्पादन के दौरान चेक किया गया है, संकलन के दौरान नहीं।

class A 
{ 
    { 
     FileReader fr = new FileReader(new File("IDonotexist.txt")); 
    } 
    public A() throws IOException 
    { 
     // TODO Auto-generated constructor stub 
    } 
    public static void main(String st[])throws Exception 
    { 
     A a = new A(); 
    } 
} 

यह अंतिम चर प्रारंभिकरण के मामले के समान है। कोड निम्नलिखित में उदाहरण के लिए, संकलक संकलन समय त्रुटि

public void calling() 
    { 
     final int i; 
     int k = 90; 
     if (k == 90) 
     { 
      i = 56; 
     } 
     System.out.println(i);//Compiler will show error here as: variable i might not have been initialized 
    } 

दिखाएगा लेकिन अगर मैं if(true) साथ शर्त if (k == 90) की जगह तो संकलक त्रुटि नहीं दिखाया जाएगा। क्योंकि संकलक अब यह जानकर कि i निश्चित रूप से कुछ मूल्य असाइन किया जा रहा है।