निर्धारित करें कि क्या कोई वर्ग जावा में इंटरफ़ेस लागू करता है


91

मेरे पास एक Classवस्तु है। मैं यह निर्धारित करना चाहता हूं कि Classवस्तु जिस प्रकार का प्रतिनिधित्व करती है वह एक विशिष्ट इंटरफ़ेस को लागू करती है। मैं सोच रहा था कि यह कैसे हासिल किया जा सकता है?

मेरे पास निम्न कोड है। मूल रूप से यह क्या करता है एक निर्दिष्ट पैकेज में सभी वर्गों की एक सरणी मिलती है। मैं फिर सरणी के माध्यम से जाना चाहता हूं और क्लास ऑब्जेक्ट्स को जोड़ना चाहता हूं जो मेरे नक्शे पर एक इंटरफ़ेस लागू करते हैं। समस्या isInstance()एक वस्तु को एक पैरामीटर के रूप में लेती है। मैं एक इंटरफ़ेस को तुरंत नहीं कर सकता। इसलिए मैं इसके साथ एक नुकसान में हूं। कोई विचार?

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
    if(clazz.isInstance(/*Some object*/)) //Need something in this if statement
    {
        retVal.put(clazz.getSimpleName(), clazz);
    }
}

जवाबों:


214

आपको उपयोग करना चाहिए isAssignableFrom:

if (YourInterface.class.isAssignableFrom(clazz)) {
    ...
}

यदि प्रोजेक्ट समान है तो यह काम करता है। लेकिन यदि आप इंटरफ़ेस कोड 1: 1 को कॉपी करते हैं, तो एक नया प्रोजेक्ट बनाएं और जार करें, फिर उस जार को एक प्लगइन के रूप में लोड करने का प्रयास करें, कॉल झूठी हो जाएगी। नाम से तुलना करें तो "काम करता है", जैसे रॉडी ने पोस्ट किया है। लेकिन मुझे नहीं पता कि जावा को अंततः संगतता की पुष्टि करने के तरीके से इसे कैसे जांचना है। नाम से एक गंदा दृष्टिकोण है। तुम्हारा ठीक है, निश्चित रूप से, अगर परियोजना समान है। ................ मैं गलत कर रहा हूं: मैं प्लगइन फाइल के लिए URLClassLoader उदाहरण बनाता हूं और इसे इस तरह लोड करता हूं। शायद मुझे एक अलग श्रेणी लोडर की कोशिश करनी चाहिए।
ड्रीम्सस्पेस राष्ट्रपति

4
आप क्लास लोडिंग समस्याएँ हैं। यदि आप एक ही क्लास को दो बार अलग-अलग क्लास लोडर से लोड करते हैं, तो दो Classइंस्टेंसेस संगत नहीं होंगे। आप त्रुटियों को देख सकते हैं जैसे java.lang.ClassCastException: com.my.CustomClass cannot be cast to com.my.CustomClassया कुछ समान रूप से अकथनीय।
फ्लावियो

मैंने अब तक विभिन्न तरीकों की कोशिश की है, और अंत में, यह पता चला कि मेरे पास मुख्य समस्या यह थी: जबकि मेरे प्लगइन और मुख्य परियोजना में इंटरफ़ेस समान थे, वे एक ही स्थान पर नहीं थे, इसलिए नाम स्थान / पता एक अलग था। Btw।, मैं अब उपयोग कर रहा हूँ: myClassLoader = new URLClassLoader(new URL[] { candidateFile.toURI().toURL() }, LoadedPlugin.class.getClassLoader());और classToLoad = Class.forName("com.blablabla.plugin.Main", true, myClassLoader);और instance = (MyIntf) classToLoad.newInstance();एक आकर्षण की तरह काम करता है।
ड्रीमस्पेस राष्ट्रपति

17

आप सभी कार्यान्वित इंटरफेस प्राप्त करने के लिए नीचे दिए गए फ़ंक्शन का उपयोग कर सकते हैं

Class[] intfs = clazz.getInterfaces();

10

आप उपयोग कर सकते हैं class.getInterfaces()और फिर यह देखने के लिए देख सकते हैं कि क्या इंटरफ़ेस क्लास है।

Class someInterface; // the interface you want to check for 
Class x; // 
Class[] interfaces = x.getInterfaces();

for (Class i : interfaces) {
    if (i.toString().equals(someInterface.toString()) {
        // if this is true, the class implements the interface you're looking for
    }
}

यह दृष्टिकोण तकनीकी रूप से काम करेगा, लेकिन बहुत सरल और क्लीनर दृष्टिकोण isAssignableFromफ्लेवियो उल्लेख के रूप में उपयोग करना है।
jwj

हां, यह सच है, हालांकि आपका उत्तर कुछ समय से अधिक समय तक बना हुआ है और मुझे लगा कि कुछ संदर्भ जोड़ना उपयोगी होगा। उपयोग करते समय isAssignableFromशायद बेहतर होता है, ऐसे उदाहरण भी हो सकते हैं, जहां आपको नामों को देखकर एक क्लास के इम्प्लायमेंट की सूची को स्कैन करने की आवश्यकता होती है।
jwj

यह वास्तव में काम नहीं करता है, getInterfaces () केवल तभी काम करता है जब वर्ग इंटरफ़ेस को सीधे लागू करता है, यदि सुपरक्लास इंटरफ़ेस को लागू करता है, या एक सुपर इंटरफ़ेस इसे विस्तारित करता है, तो वह इंटरफ़ेस getInterfaces () द्वारा वापस नहीं किया जाएगा। आपको क्लास को लागू करने वाले सभी इंटरफेस प्राप्त करने के लिए सभी सुपर वर्गों और इंटरफेस के पेड़ को पार करने की आवश्यकता है।
जेम्स रॉपर

हालांकि यह सवाल नहीं था।
फ्रोज़न मटर की रोडी

1

आप ".class" जोड़कर उदाहरण भी सेट कर सकते हैं

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
    if(Interface.class.isAssignableFrom(clazz))
    {
        retVal.put(clazz.getSimpleName(), clazz);
    }
}

2
इस दृष्टिकोण को देखने वाले किसी के लिए, कृपया फ्लेवियो के उत्तर पर विचार करें। ध्यान दें कि इस उदाहरण में कोड कुछ चीजें करता है जो तत्काल समझ ClassUtilsमें नहीं आता है: जावा का हिस्सा नहीं है (यह अमरूद या वसंत और अन्य रूपरेखाओं में है), Interfaceऊपर वर्णित शब्द का अर्थ है एक विशिष्ट इंटरफ़ेस का परीक्षण किया जाना () यानी, यह इस संदर्भ में एक जावा कीवर्ड नहीं है), और इसका उद्देश्य retValकहीं भी समझाया या उल्लेख नहीं किया गया है।
jwj
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.