2011-02-08 4 views
21

मैं जावा प्रतिबिंब एपीआई के साथ खेल रहा था और देखा कि विविध तर्क सूची वाले विधियां क्षणिक बन जाती हैं। यह संदर्भ क्यों है और इस संदर्भ में transient कीवर्ड का अर्थ क्या है?क्यों varargs के साथ जावा विधियों क्षणिक के रूप में पहचाना?

जावा शब्दावली से, क्षणिक:

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

हालांकि यह परिभाषा विधियों के बारे में कुछ भी नहीं कहती है। कोई विचार?

import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 

public class Dummy { 
    public static void main(String[] args) { 
     for(Method m : Dummy.class.getDeclaredMethods()){ 
      System.out.println(m.getName() + " --> "+Modifier.toString(m.getModifiers())); 
     } 
    } 

    public static void foo(int... args){} 
} 

आउटपुट:

main --> public static 
foo --> public static transient 
+2

ओह, दिलचस्प! मैंने सोचा था कि विधियों को क्रमबद्ध नहीं किया गया है, इसलिए अब मैं उत्सुक हूं। – Kris

+0

कमाल की खोज। :) – biziclop

+1

@biziclop क्या आश्चर्यजनक है, 'Modifier.toString (-1)' का प्रयास करें, बहुत बेहतर – bestsss

उत्तर

22

क्रमबद्ध javassist AccessFlag

public static final int TRANSIENT = 0x0080; 
public static final int VARARGS = 0x0080; 

के कोड में पाया जा सकता ऐसा प्रतीत होता है दोनों एक ही मान हैं। और चूंकि transient का अर्थ विधियों के लिए कुछ भी नहीं है, जबकि varargs का अर्थ फ़ील्ड के लिए कुछ भी नहीं है, उनके लिए यह ठीक है।

लेकिन Modifier कक्षा के लिए यह ठीक नहीं है, इसे ध्यान में रखना न करें। मैं इसके बारे में एक मुद्दा दर्ज करूंगा। इसे एक नई स्थिरता की आवश्यकता है - VARARGS और एक नई विधि - isVarargs(..)। और toString() विधि को "क्षणिक/varargs" शामिल करने के लिए फिर से लिखा जा सकता है।

+2

को उद्धृत करने के लिए – bestsss

+0

@bestsss - यह सच है। लेकिन एक और विधि जोड़ा जा सकता है जो 'AccessibleObject' को तर्क के रूप में भी लेता है। या सिर्फ संदेश जोड़ने के लिए (मेरा अपडेट देखें) – Bozho

+0

'AccessibleObject' क्लास के लिए काम नहीं करेगा, केवल ऑब्जेक्ट – bestsss

6

इस कार्यान्वयन में एक बग की तरह दिखता है। मुझे लगता है कि मूल कारण यह हो सकता है कि क्षणिक फ़ील्ड के लिए .class फ़ाइल में बिट सेट varargs विधियों के लिए समान है (http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf, पृष्ठ 122 और 119 देखें)।

एक जवाब की
+0

क्यों बग? आप किसी भी मनमाना संख्या को पारित कर सकते हैं, और आपको कुछ परिणाम मिलेगा – bestsss

+0

@ बेस्ट्सएसएस- यह एक अच्छा मुद्दा है। मैं इस धारणा के तहत था कि 'संशोधक' वर्ग के बारे में अधिक जानकारी थी कि झंडे कहां से आ रहे थे।स्रोत – templatetypedef

+0

+1 Modifier.toString() एक एकल int लेता है और .. इसे वहां से ले जाता है; चूंकि फ़ील्ड/विधि में कोई अंतर नहीं है, यह कभी भी सही नहीं हो सकता – Bozho

3

एक क्षणिक क्षेत्र के लिए ध्वज एक विधि के संदर्भ में अधिभारित किया गया है जिसका अर्थ है कि विधि एक vararg विधि है।

इसी तरह, एक अस्थिर क्षेत्र के लिए ध्वज एक विधि के संदर्भ में अधिभारित किया गया है जिसका अर्थ है कि विधि एक पुल विधि है।

देखें: http://java.sun.com/docs/books/vmspec/2nd-edition/ClassFileFormat-Java5.pdf

पृष्ठों 118-122 (या पीडीएफ फाइल में 26-30)

अद्यतन

Modifier.java के लिए स्रोत कोड पढ़ना इस का पहला वाक्य की पुष्टि करता है उत्तर ("एक क्षणिक क्षेत्र के लिए ध्वज अधिभारित किया गया है")। यहां प्रासंगिक स्रोत कोड है:

// Bits not (yet) exposed in the public API either because they 
// have different meanings for fields and methods and there is no 
// way to distinguish between the two in this class, or because 
// they are not Java programming language keywords 
static final int BRIDGE = 0x00000040; 
static final int VARARGS = 0x00000080; 
static final int SYNTHETIC = 0x00001000; 
static final int ANNOTATION = 0x00002000; 
static final int ENUM  = 0x00004000; 
static final int MANDATED = 0x00008000; 
+0

यह उत्तर सही उत्तर के सबसे नज़दीक है और स्वीकार्य उत्तर होना चाहिए । क्लासफाइलफॉर्मैट का लिंक टूटा हुआ है। – Jason