2011-04-05 17 views
19

के लिए जावप के आउटपुट को समझना एक बहुत ही सरल हैलोवर्ल्ड एप्लिकेशन पर जावप चलाते समय मुझे निरंतर पूल के आसपास आउटपुट पर कुछ भ्रम है।कॉन्स्टेंट पूल

टेस्ट कोड

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

Javap -c -verbose निर्गम (कतरना)

// Header + consts 1..22 snipped 
const #22 = String  #23; // hello world 
const #23 = Asciz  hello world; 

public static void main(java.lang.String[]); 
    Signature: ([Ljava/lang/String;)V 
    Code: 
    Stack=2, Locals=1, Args_size=1 
    0: getstatic  #16; //Field java/lang/System.out:Ljava/io/PrintStream; 
    3: ldc  #22; //String hello world 
    5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    8: return 
    // Debug info snipped 
} 

, ठीक है तो लाइन 3 पर हम देखते हैं "हैलो दुनिया" का एक धक्का निरंतर # 22 के माध्यम से ढेर पर, लेकिन const # 23 वास्तविक मान धारण करता है। मुझे लगता है कि मैं # (संख्या) का अर्थ प्रिंटआउट के दाईं ओर दिखाई देने पर थोड़ा उलझन में हूं।

Oracle/Sun's man page for javap वांछित होने के लिए बहुत अधिक छोड़ देता है।

उत्तर

22

सभी अपने class, interface, field नाम और string स्थिरांक जावा निरंतर पूल में जाने।

अनुसार वीएम युक्ति (http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):

constant_pool ढांचे (§4.4) विभिन्न स्ट्रिंग स्थिरांक, वर्ग और इंटरफ़ेस का प्रतिनिधित्व नाम, क्षेत्र नाम, और अन्य स्थिरांक की एक टेबल है कि क्लासफाइल संरचना और संरचनाओं के के भीतर संदर्भित किया जाता है। प्रत्येक स्थिर_पूल तालिका प्रविष्टि का प्रारूप को इसके पहले "टैग" बाइट द्वारा इंगित किया गया है। निरंतर_पूल तालिका को 1 से स्थिर_pool_count-1 तक अनुक्रमित किया गया है।

नीचे की तरह निरंतर पूल कुछ के मामले में

तो के रूप में देखा जा सकता है:

const #22 = String  #23; // hello world 
const #23 = Asciz  hello world; 

# 22 (सूचकांक 22) पर मान प्रकार String की है और इसके मूल्य शून्य है समाप्त सी स्ट्रिंग (Asciz) hello world सूचकांक 23 पर है।

+0

'jdk-7' (http://bugs.sun.com/view_bug.do?bug_id=6868539) के रूप में यह' utf8' है और 'asciz' नहीं है – Eugene

3

पूल प्रविष्टि # 22 एक java.lang.String ऑब्जेक्ट है। प्रविष्टि # 23 उस स्ट्रिंग को बनाने के लिए उपयोग किए गए वर्णों की सरणी है।

Java VM Spec जावप के लिए "अनुपलब्ध मैनुअल" है।

5

जावा स्थिर पूल स्ट्रिंग को संग्रहीत करते समय दो अलग-अलग प्रकार की प्रविष्टियों को संग्रहीत करता है। सबसे पहले, यह स्ट्रिंग अक्षर को यूटीएफ -8 एन्कोडेड डेटा (यहां, स्थिर # 23) के रूप में संग्रहीत करता है। दूसरा, यह एक स्ट्रिंग एंट्री (# 22) भी संग्रहीत करता है जो दर्शाता है कि निरंतर # 23 की सामग्री String बनाने के लिए उपयोग की जानी चाहिए। मुझे लगता है कि इसका कारण यह है कि जेवीएम प्रत्येक वर्ग के साथ "रनटाइम निरंतर पूल" को जोड़ता है जिसमें दिए गए स्थिरांक के गतिशील कार्यान्वयन होते हैं। स्ट्रिंग्स के लिए, यह दिए गए वर्ण रखने वाले इंटर्न वाले String ऑब्जेक्ट का संदर्भ हो सकता है। यूटीएफ -8 निरंतर डेटा में स्ट्रिंग अक्षर (उदाहरण के लिए, फ़ील्ड और कक्षाओं का नामकरण) के अलावा अन्य उपयोग हैं, इसलिए यह अतिरिक्त संकेत चिंता को अलग करने के लिए एक उचित तरीका प्रतीत होता है।

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