किसी वस्तु का वर्ग कैसे निर्धारित करें?


510

यदि वर्ग Bऔर वर्ग वर्ग का Cविस्तार करते हैं Aऔर मेरे पास प्रकार की वस्तु है Bया C, मैं यह कैसे निर्धारित कर सकता हूं कि यह किस प्रकार का उदाहरण है?


14
@starblue कास्टिंग पहली चीज़ होगी जो दिमाग में आती है। मुझे संदेह है कि अगर इसके लिए कोई आवश्यकता नहीं थी तो इंस्टोऑफ़ ऑपरेटर मौजूद होगा।
b1nary.atr0phy

@ b1nary.atr0phy पहले isntanceof ऑपरेटर का उपयोग करना अच्छा नहीं होगा। अगर वहाँ एक असंगत प्रकार के लिए एक डाली है, मुझे विश्वास है कि एक ClassCastException में परिणाम होगा
committedandroider

जवाबों:


801
if (obj instanceof C) {
//your code
}

31
किसी वस्तु का वर्ग का उदाहरण नहीं होने पर रिवर्स चेक या कैसे चेक करना उपयोगी है:if(!(obj instanceof C))
Dzhuneyt

32
मेरा मानना ​​है कि getClass () विधि मूल प्रश्न का उत्तर है। इस मामले में (obj Instof A) भी "सही" आउटपुट देगा, लेकिन आशय चित्र में ऑब्जेक्ट के रनटाइम वर्ग को खोजने का है। यदि Parent1 चाइल्ड 1 और चाइल्ड 2 द्वारा बढ़ाया गया है, तो निम्नलिखित code चाइल्ड 1 चाइल्ड 1 = नया चाइल्ड 1 () देखें; पेरेंट 1 पेरेंट चिल्ड = नया चाइल्ड 2 (); चाइल्ड 2 चाइल्ड 2 = नया चाइल्ड 2 (); (चाइल्ड 1 इंस्टो पेरेंट 1); (चाइल्ड 1 इंस्टोफ़ चाइल्ड 1); (पेरेंट चिल्ड इंफोऑफ चाइल्ड 2); (पेरेंट चिल्ड इंस्टा पेरेंट १); (parentChild उदाहरण 1 चाइल्ड); code , यह उदाहरण के इरादे को साफ कर सकता है।
भावेश अग्रवाल

निश्चित रूप से एक इंटरफेस के निर्माण का विकल्प
जॉनमेरिनो 22

3
क्या होगा अगर मेरे पास एकल इंटरफ़ेस लागू करने वाली दो कक्षाएं हैं? मैं वस्तु के सटीक वर्ग को कैसे अलग करूं?
ओलिव

3
एक बात हालांकि, यह काम नहीं करता है अगर obj अशक्त है। समाधान तब ParentInterface.class.isAssignableFrom (Child.class) होगा
alexbt

351

Object.getClass () का उपयोग करें । यह ऑब्जेक्ट का रनटाइम प्रकार लौटाता है।


12
यह वास्तव में है कि आप किसी वस्तु के वर्ग का निर्धारण कैसे करते हैं
AA_PV

निर्दोष उत्तर @Bill
गौरव

1
यह निश्चित नहीं है कि यह सबसे लोकप्रिय उत्तर क्यों नहीं है
ईकसैल

178

एकाधिक सही उत्तर प्रस्तुत किए गए थे, लेकिन अभी भी अधिक विधियां हैं: Class.isAssignableFrom()और बस वस्तु को डालने का प्रयास (जो फेंक सकता है ClassCastException)।

संभव तरीके संक्षेप में

यदि किसी वस्तु objका प्रकार है तो परीक्षण करने के संभावित तरीकों को संक्षेप में बताएं C:

// Method #1
if (obj instanceof C)
    ;

// Method #2
if (C.class.isInstance(obj))
    ;

// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
    ;

// Method #4
try {
    C c = (C) obj;
    // No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}

// Method #5
try {
    C c = C.class.cast(obj);
    // No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}

nullहैंडलिंग में अंतर

nullहालांकि संभालने में एक अंतर है :

  • पहले 2 तरीकों में भाव का मूल्यांकन करने के falseअगर objहै null( nullकुछ भी उदाहरण नहीं है)।
  • 3 विधि NullPointerExceptionस्पष्ट रूप से फेंक देगी ।
  • 4 वें और 5 वें तरीके इसके विपरीत हैं nullक्योंकि nullकिसी भी प्रकार के लिए डाली जा सकती हैं!

याद रखने के लिए: किसी भी प्रकार का उदाहरण null नहीं है , लेकिन इसे किसी भी प्रकार में डाला जा सकता है

टिप्पणियाँ

  • Class.getName()यदि " ऑब्जेक्ट का प्रकार नहीं है, Cलेकिन इसका एक उपवर्ग है, तो इसका " एज़ - इंस्ट -ऑफ " टेस्ट करने के लिए उपयोग नहीं किया जाना चाहिए , इसमें पूरी तरह से अलग नाम और पैकेज हो सकता है (इसलिए वर्ग के नाम स्पष्ट रूप से मेल नहीं खाएंगे) लेकिन यह है अभी भी टाइप है C
  • एक ही वंशानुगत कारण के Class.isAssignableFrom()लिए सममित नहीं है : यदि का प्रकार एक उपवर्ग है तो
    obj.getClass().isAssignableFrom(C.class)वापस आ जाएगा ।falseobjC

6
यह विभिन्न तरीकों में से कई नुकसानों का एक बहुत बड़ा सारांश है। इस तरह के एक पूर्ण लिखने के लिए धन्यवाद!
केल्सिन

32

आप उपयोग कर सकते हैं:

Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object

HTH। लेकिन मुझे लगता है कि ज्यादातर समय यह अच्छा अभ्यास नहीं है कि नियंत्रण प्रवाह या कुछ इसी तरह के लिए ...


मैंने इसका उपयोग जेनेरिक लकड़हारा बनाने के लिए किया था, इसलिए मैंने लकड़हारे को ऑब्जेक्ट भेजा, और यह हर बार लॉग टैग या लॉग स्ट्रिंग देने के बजाय ऑब्जेक्ट के वर्ग नाम के आधार पर लॉग करता है। धन्यवाद
MBH

24

सुझाए गए तरीकों में से किसी भी उपयोग को एक कोड गंध माना जाता है जो खराब ओओ डिजाइन में आधारित है।

यदि आपका डिज़ाइन अच्छा है, तो आपको अपने आप को उपयोग करने की आवश्यकता नहीं मिलनी चाहिए getClass()या instanceof

सुझाए गए तरीकों में से कोई भी करेगा, लेकिन डिज़ाइन-वार को ध्यान में रखने के लिए बस कुछ।


3
हाँ, शायद getClass और Instof के 99% उपयोगों को पॉलीमॉर्फिक मेथड कॉल से टाला जा सकता है।
छिपकली

3
मैं समझौते में हूं। इस मामले में मैं xml से उत्पन्न वस्तुओं के साथ काम कर रहा हूं जो खराब रूप से डिजाइन किए गए स्कीमा का अनुसरण करते हैं जिनके पास मेरे स्वामित्व नहीं है।
वाहक

28
नेकलेस नहीं। कभी-कभी इंटरफेस को अलग करना अच्छा होता है। ऐसे समय होते हैं जब आप जानना चाहते हैं कि क्या ए एक बी है, लेकिन आप यह अनिवार्य नहीं करना चाहते हैं कि ए एक बी है, क्योंकि केवल ए को सबसे अधिक कार्यक्षमता के लिए आवश्यक है - बी में वैकल्पिक कार्यक्षमता है।
MetroidFan2002

8
इसके अलावा, ऐसे समय होते हैं जब आपको यह सुनिश्चित करने की आवश्यकता होती है कि ऑब्जेक्ट उसी वर्ग का है जिसकी आप तुलना कर रहे हैं; उदाहरण के लिए, मैं अपनी कक्षा बनाते समय ऑब्जेक्ट के बराबर विधि को ओवरराइड करना पसंद करता हूं। मैं हमेशा आने वाली वस्तु का सत्यापन उसी वर्ग से करता हूं।
स्टैकऑवरफ्लो

58
इसके अलावा, मैं कहूंगा कि लोगों को कुछ भी बताए बिना बुरा है, ठीक इसी तरह से क्यों या किसी कागज, पुस्तक, या किसी अन्य संसाधन का संदर्भ देते हुए, जहां समस्या को समझाया गया है, रचनात्मक नहीं है। इसलिए और यह जानते हुए कि मैं StackOverflow में हूं, मुझे नहीं पता कि लोगों ने इस उत्तर को इतना अधिक क्यों उकेरा है। यहाँ कुछ बदल रहा है ...
एड्रियान पेरेज़

15

हम इस मामले में प्रतिबिंब का उपयोग कर सकते हैं

objectName.getClass().getName();

उदाहरण:-

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String name = request.getClass().getName();
}

इस स्थिति में आपको उस वर्ग का नाम मिल जाएगा, जो ऑब्जेक्ट HttpServletRequestरेफरेंस वैरिएबल को पास करता है।


यह सही है। केवल obj.getClass()कक्षा का उपयोग करके नाम, उपसर्ग को शब्द से class
लौटा देंगे

request.getClass().getName();सभी पैकेज प्रिंट! वर्ग नाम के साथ
शायर

13

.isInstance" Class" वर्ग पर एक विधि भी है । यदि आप एक वस्तु के वर्ग मिल के माध्यम से myBanana.getClass()आप अपने वस्तु देख सकते हैं myAppleके रूप में एक ही कक्षा का एक उदाहरण है myBananaके माध्यम से

myBanana.getClass().isInstance(myApple)

1

isinstance()यदि आप रन टाइम में जानना चाहते हैं तो चेक करना पर्याप्त नहीं होगा। उपयोग:

if(someObject.getClass().equals(C.class){
    // do something
}

0

मैं अपने GeneralUtils वर्ग में झटका फ़ंक्शन का उपयोग करता हूं, यह जांचें कि यह उपयोगी हो सकता है

    public String getFieldType(Object o) {
    if (o == null) {
        return "Unable to identify the class name";
    }
    return o.getClass().getName();
}

0

मैंने स्विच केस का उपयोग करने के बजाय रनटाइम पर ऑब्जेक्ट उदाहरण प्राप्त करने के लिए जावा 8 जेनरिक का उपयोग किया

 public <T> void print(T data) {
    System.out.println(data.getClass().getName()+" => The data is " + data);
}

किसी भी प्रकार का डेटा पास करें और यह विधि उस डेटा का प्रकार प्रिंट करेगी जिसे आपने कॉल करते समय पास किया था। जैसे

    String str = "Hello World";
    int number = 10;
    double decimal = 10.0;
    float f = 10F;
    long l = 10L;
    List list = new ArrayList();
    print(str);
    print(number);
    print(decimal);
    print(f);
    print(l);
    print(list);

निम्नलिखित आउटपुट है

java.lang.String => The data is Hello World
java.lang.Integer => The data is 10
java.lang.Double => The data is 10.0
java.lang.Float => The data is 10.0
java.lang.Long => The data is 10
java.util.ArrayList => The data is []
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.