2013-07-26 10 views
5

के आधार पर इलाज जब मैं संकलन:javac स्थिर अंतिम अलग ढंग से काम विधि

public static final boolean FOO = false; 
public static final void fooTest() { 
    if (FOO) { 
     System.out.println("gg"); 
    } 
} 

मैं एक खाली विधि fooTest() {} मिलता है। हालांकि जब मैं संकलित करता हूं:

static boolean isBar = false; 
public static final boolean BAR = isBar; 
public static final void fooTest() { 
    if (BAR) { 
     System.out.println("gg"); 
    } 
} 

यदि कथन कथित कक्षा फ़ाइल में शामिल है। क्या इसका मतलब जावा में स्थिर फाइनल के दो अलग-अलग "प्रकार" हैं, या यह सिर्फ एक कंपाइलर अनुकूलन है?

+5

कंपाइलर अभिव्यक्तियों का मूल्यांकन कर सकता है जिसमें संकलन समय पर केवल 'स्थिर अंतिम' और शाब्दिक स्थिरांक शामिल हैं, और आवश्यकतानुसार अनुकूलन निष्पादित करते हैं। संकलन समय पर पहली अभिव्यक्ति का मूल्यांकन किया जा सकता है; दूसरा नहीं कर सकता, क्योंकि यह एक गैर-अंतिम अभिव्यक्ति पर निर्भर करता है। – dasblinkenlight

+2

जिसका मतलब यह नहीं है कि जेआईटी बाइटकोड संकलन इसे निश्चित रूप से छोड़ देगा। –

उत्तर

7

पहले मामले में, कंपाइलर अनुकूलन करता है। यह जानता है कि Foo हमेशा false होगा और कोड को कभी भी नहीं पहुंचाएगा।

दूसरे मामले में, आप गैर-अंतिम चर isBar से BAR का मान असाइन कर रहे हैं। कंपाइलर यह नहीं बता सकता कि परिवर्तनीय isBar कहीं और संशोधित किया गया है, खासकर अगर यह निजी नहीं है। इसलिए यह BAR के मान के बारे में निश्चित नहीं है। इसलिए वह अनुकूलन नहीं कर सकता है।

+1

यह वास्तव में एक संकलक अनुकूलन नहीं है। यह जावा भाषा विशिष्टता द्वारा आवश्यक व्यवहार है। (* संकलन-समय निरंतर * जादू वाक्यांश है।) 'निजी' अप्रासंगिक है - बिना किसी स्रोत कोड के एक अलग पैकेज में एक भिन्न फ़ाइल में हो सकता है। –

2

पहले मामले में static final फ़ील्ड स्थिरांक हैं जो compile समय पर ज्ञात हैं। तो संकलक अनुकूलित करता है और constant इनलाइन करता है।

दूसरे मामले में फ़ील्ड non-finalvariable है और इसे संकलक द्वारा रेखांकित नहीं किया जा सकता है क्योंकि यह बदल सकता है।

class Test{ 
    public static final boolean BOOL = true; //CONSTANT KNOWN AT COMPILE TIME 


    public void someMethod(){ 
     while(BOOL){ 
      //some code 
     } 
    } 


    //OPTIMIZED VERSION DONE BY COMPILER 
    public void someMethod(){ 
     while(true){ //There is no need for accessing BOOL if it is not going to change and compiler understands that so inlines the value of constant 


     } 
    } 

} 

आप कुछ दे-संकलक उपकरण का उपयोग कर संकलित कोड देख सकते हैं और आप अनुकूलित विधि है कि मैं वर्ग फ़ाइल में लिखा है मिल जाएगा।

2

यह पूरी तरह से कंपाइलर अनुकूलन का मामला है जहां यह प्रत्यक्ष असाइनमेंट को अनदेखा करता है और साहित्यिक पर अप्रत्यक्ष असाइनमेंट पर विचार करता है।

0

स्मृति के भीतर केवल एक मौजूदा स्थिर मूल्य हो सकता है। पहले ब्लॉक में, स्थिर अंतिम चर FOO को झूठा मान सेट किया गया है जो संकलक को ज्ञात है और इसलिए इसमें इसमें कथन का अनुकूलन है। लेकिन दूसरे बयान में, BAR अंतिम स्थैतिक चर को isBar स्थिर वैरिएबल मान असाइन किया गया है, जो बदले में कंपाइलर को कथन को अनुकूलित नहीं करता है (क्योंकि isBar कोई भी बूलियन मान हो सकता है और इसे निर्धारित नहीं किया जा सकता क्योंकि जावा polymorphism का समर्थन करता है और मान असाइन किए जाते हैं रन टाइम के दौरान गतिशील रूप से चर के लिए।), इसलिए दूसरे ब्लॉक में स्थैतिक चर मेमोरी स्थिति संकलक के लिए महत्वपूर्ण है, जहां पहले ब्लॉक में वैल्यू को विभिन्न चर के बीच किसी भी असाइनमेंट के बिना जाना जाता है और इसे अनुकूलित किया जाता है।

संबंधित मुद्दे