जांचें कि क्या एक क्लास ऑब्जेक्ट जावा में किसी अन्य क्लास ऑब्जेक्ट का उपवर्ग है


196

मैं जावा के प्रतिबिंब एपीआई के साथ खेल रहा हूं और कुछ क्षेत्रों को संभालने की कोशिश कर रहा हूं। अब मैं अपने खेतों के प्रकार की पहचान करने के साथ फंस गया हूं। स्ट्रिंग्स आसान है, बस करो myField.getType().equals(String.class)। अन्य गैर-व्युत्पन्न वर्गों के लिए भी यही लागू होता है। लेकिन मैं व्युत्पन्न वर्ग की जाँच कैसे करूँ? जैसे LinkedListउपवर्ग List। मुझे कोई विधि isSubclassOf(...)या extends(...)तरीका नहीं मिल रहा है । क्या मुझे सभी के माध्यम से चलने की ज़रूरत है getSuperClass()और अपने स्वयं के द्वारा मेरे सुपरकेल्स को ढूंढना है?


11
LinkedListका उपवर्ग नहीं है List। यह एक कार्यान्वयन है List
टीजे क्राउडर

2
उप-प्रकार एक बेहतर शब्द हो सकता है
जेपी

जवाबों:


402

आप यह विधि चाहते हैं:

boolean isList = List.class.isAssignableFrom(myClass);

जहां सामान्य तौर पर, List(ऊपर) को प्रतिस्थापित किया जाना चाहिए superclassऔर उसके साथ प्रतिस्थापित किया myClassजाना चाहिएsubclass

से JavaDoc :

यह निर्धारित करता है कि इस Classऑब्जेक्ट द्वारा दर्शाया गया वर्ग या इंटरफ़ेस या तो एक ही है, या निर्दिष्ट Classपैरामीटर द्वारा दर्शाया गया वर्ग या इंटरफ़ेस का सुपरक्लास या सुपरनट्रैस है । trueअगर ऐसा है तो लौटता है; अन्यथा यह वापस आ जाता है false। यदि यह Classऑब्जेक्ट एक आदिम प्रकार का प्रतिनिधित्व करता है, तो यह विधि वापस आती है trueयदि निर्दिष्ट Classपैरामीटर बिल्कुल यह Classऑब्जेक्ट है; अन्यथा यह वापस आ जाता है false

संदर्भ:


सम्बंधित:

क) जाँच करें कि क्या ऑब्जेक्ट क्लास या इंटरफ़ेस का एक उदाहरण है (उपवर्ग सहित) जिसे आप संकलन समय पर जानते हैं:

boolean isInstance = someObject instanceof SomeTypeOrInterface;

उदाहरण:

assertTrue(Arrays.asList("a", "b", "c") instanceof List<?>);

b) जांचें कि क्या कोई ऑब्जेक्ट क्लास या इंटरफेस (उपवर्ग सहित) का एक उदाहरण है, जिसे आप केवल रनटाइम पर जानते हैं:

Class<?> typeOrInterface = // acquire class somehow
boolean isInstance = typeOrInterface.isInstance(someObject);

उदाहरण:

public boolean checkForType(Object candidate, Class<?> type){
    return type.isInstance(candidate);
}

20
योजना पर ध्यान दें: SUPERCLASS.isAssignableFrom(SUBCLASS)इसने मुझे पहले भ्रमित किया, वास्तव में नामकरण पर विचार करना वास्तव में स्पष्ट है।
कोडप्लब

7
@ ट्रूडल मैं सहमत हूं। ऐसा कुछ SUPERCLASS.isExtendedBy(SUBCLASS)समझना बहुत आसान होगा
सीन पैट्रिक फ्लॉयड

@SeanPatrickFloyd वास्तव isExtendedByमें एक बुरा नाम है जो CLASS.isAssignableFrom(CLASS)सच होगा (और इसलिए CLASS.isExtendedBy(CLASS)भी)। यह वह नहीं होगा जिसकी मुझे उम्मीद थी।
Qw3ry

@ Qw3ry हाँ, मैं मान रहा हूँ कि आपी लेखकों ने भी क्या सोचा है :-)
सीन पैट्रिक फ्लोयड

24

एक अन्य विकल्प है:

Object o =...
if (o instanceof Number) {
  double d = ((Number)o).doubleValue(); //this cast is safe
}

अच्छी कॉल (+1)। और फिर दो तंत्रों का संयोजन भी है: Class.isInstance(object) download.oracle.com/javase/6/docs/api/java/lang/…
Sean Patrick Floyd

5
इसका मतलब यह होगा, कि आप इसे समझाना चाहते हैं Field। लेकिन मैं सिर्फ अपनी कक्षा और इसके क्षेत्रों में "देखना" चाहता हूं, "उन्हें आज़माना नहीं चाहता"।
तृष्णा

मैं इस विधि को "isAssignableFrom" की तुलना में बहुत अधिक स्वच्छ और स्पष्ट देखता हूं, इस मामले में आपको किसी वस्तु के वंशानुक्रम वृक्ष की जांच करने की आवश्यकता है।
cbuchart

ध्यान रखें कि instanceofमाता-पिता के लिए भी काम करता है (इस मामले में Number) केवल बच्चे ही नहीं
lukaszrys

9

Instof वस्तुओं पर, उदाहरणों पर काम करता है। कभी-कभी आप कक्षाओं के साथ सीधे काम करना चाहते हैं। इस स्थिति में आप asSubClass का उपयोग कर सकते हैं क्लास क्लास पद्धति का । कुछ उदाहरण:

1)

    Class o=Object.class;
    Class c=Class.forName("javax.swing.JFrame").asSubclass(o);

यह आसानी से गुजर जाएगा क्योंकि JFrame ऑब्जेक्ट का उपवर्ग है। c में JFrame वर्ग का प्रतिनिधित्व करने वाला एक क्लास ऑब्जेक्ट होगा।

2)

    Class o=JButton.class;
    Class c=Class.forName("javax.swing.JFrame").asSubclass(o);

यह एक java.lang.ClassCastException लॉन्च करेगा क्योंकि JFrame JButton का उपवर्ग नहीं है। c को इनिशियलाइज़ नहीं किया जाएगा।

3)

    Class o=Serializable.class;
    Class c=Class.forName("javax.swing.JFrame").asSubclass(o);

यह आसानी से गुजर जाएगा क्योंकि JFrame java.io.Serializable इंटरफ़ेस को लागू करता है। c में JFrame वर्ग का प्रतिनिधित्व करने वाला एक क्लास ऑब्जेक्ट होगा।

बेशक आवश्यक आयात को शामिल किया जाना है।


5

यह मेरे लिए काम करता है:

protected boolean isTypeOf(String myClass, Class<?> superClass) {
    boolean isSubclassOf = false;
    try {
        Class<?> clazz = Class.forName(myClass);
        if (!clazz.equals(superClass)) {
            clazz = clazz.getSuperclass();
            isSubclassOf = isTypeOf(clazz.getName(), superClass);
        } else {
            isSubclassOf = true;
        }

    } catch(ClassNotFoundException e) {
        /* Ignore */
    }
    return isSubclassOf;
}

1
अच्छा काम करता है, लेकिन आपको java.lang.Object जो एक सुपर क्लास नहीं है के मामले में clazz = clazz.getSuperclass () के बाद एक अशक्त चेक जोड़ना पड़ सकता है।
जोनास पेडर्सन

4

यह @ schuttek के उत्तर का एक उन्नत संस्करण है। यह सुधार हुआ है क्योंकि यह सही ढंग से प्राइमिटिव्स के लिए गलत लौटाता है (जैसे कि isSubclassOf (int.class, Object.class) => false) और यह भी सही ढंग से इंटरफेस (जैसे IsSubclassOf (HashMap.class, Map.class) => true) को हैंडल करता है।

static public boolean isSubclassOf(final Class<?> clazz, final Class<?> possibleSuperClass)
{
    if (clazz == null || possibleSuperClass == null)
    {
        return false;
    }
    else if (clazz.equals(possibleSuperClass))
    {
        return true;
    }
    else
    {
        final boolean isSubclass = isSubclassOf(clazz.getSuperclass(), possibleSuperClass);

        if (!isSubclass && clazz.getInterfaces() != null)
        {
            for (final Class<?> inter : clazz.getInterfaces())
            {
                if (isSubclassOf(inter, possibleSuperClass))
                {
                    return true;
                }
            }
        }

        return isSubclass;
    }
}

3

एक पुनरावर्ती विधि यह जांचने के लिए कि क्या कोई Class<?>अन्य का उप वर्ग है Class<?>...

@Tra Kra के उत्तर का उन्नत संस्करण :

protected boolean isSubclassOf(Class<?> clazz, Class<?> superClass) {
    if (superClass.equals(Object.class)) {
        // Every class is an Object.
        return true;
    }
    if (clazz.equals(superClass)) {
        return true;
    } else {
        clazz = clazz.getSuperclass();
        // every class is Object, but superClass is below Object
        if (clazz.equals(Object.class)) {
            // we've reached the top of the hierarchy, but superClass couldn't be found.
            return false;
        }
        // try the next level up the hierarchy.
        return isSubclassOf(clazz, superClass);
    }
}

3

// विरासत

    class A {
      int i = 10;
      public String getVal() {
        return "I'm 'A'";
      }
    }

    class B extends A {
      int j = 20;
      public String getVal() {
        return "I'm 'B'";
      }
    }

    class C extends B {
        int k = 30;
        public String getVal() {
          return "I'm 'C'";
        }
    }

// तरीके

    public static boolean isInheritedClass(Object parent, Object child) {
      if (parent == null || child == null) {
        return false;
      } else {
        return isInheritedClass(parent.getClass(), child.getClass());
      }
    }

    public static boolean isInheritedClass(Class<?> parent, Class<?> child) {
      if (parent == null || child == null) {
        return false;
      } else {
        if (parent.isAssignableFrom(child)) {
          // is child or same class
          return parent.isAssignableFrom(child.getSuperclass());
        } else {
          return false;
        }
      }
    }

// कोड का परीक्षण करें

    System.out.println("isInheritedClass(new A(), new B()):" + isInheritedClass(new A(), new B()));
    System.out.println("isInheritedClass(new A(), new C()):" + isInheritedClass(new A(), new C()));
    System.out.println("isInheritedClass(new A(), new A()):" + isInheritedClass(new A(), new A()));
    System.out.println("isInheritedClass(new B(), new A()):" + isInheritedClass(new B(), new A()));


    System.out.println("isInheritedClass(A.class, B.class):" + isInheritedClass(A.class, B.class));
    System.out.println("isInheritedClass(A.class, C.class):" + isInheritedClass(A.class, C.class));
    System.out.println("isInheritedClass(A.class, A.class):" + isInheritedClass(A.class, A.class));
    System.out.println("isInheritedClass(B.class, A.class):" + isInheritedClass(B.class, A.class));

//परिणाम

    isInheritedClass(new A(), new B()):true
    isInheritedClass(new A(), new C()):true
    isInheritedClass(new A(), new A()):false
    isInheritedClass(new B(), new A()):false
    isInheritedClass(A.class, B.class):true
    isInheritedClass(A.class, C.class):true
    isInheritedClass(A.class, A.class):false
    isInheritedClass(B.class, A.class):false
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.