2016-01-08 4 views
5

हाल ही में एक प्रोजेक्ट जिस पर मैंने काम किया है, हाल ही में जावा 7 से जावा 8 पर स्विच किया गया है। मैं उन इंटरफेस को ढूंढने में सक्षम होना चाहता हूं जिनके पास हमारे कोड बेस में कार्यात्मक इंटरफेस पेश करने के लिए अभ्यर्थियों के रूप में एक सार तत्व है। (@FunctionalInterface के रूप में मौजूदा इंटरफेस को एनोटेट करना, java.util.function में इंटरफ़ेस से उन्हें विस्तारित करना, या संभवतः उन्हें बस बदलना)।मैं इंटरफेस के लिए जावा कोड बेस कैसे खोज सकता हूं जिसमें एक विधि है?

+1

यह इंटेलिजे में एक निरीक्षण के रूप में उपलब्ध है। एक निरीक्षण प्रोफ़ाइल बनाएं जिसमें केवल यह निरीक्षण हो, और इसे अपने प्रोजेक्ट पर चलाएं। –

+0

इस परिवर्तन के रूप में केस-दर-केस विश्लेषण की आवश्यकता होगी, और, एनोटेशन जोड़ने के अलावा, अन्य 2 समाधानों को महत्वपूर्ण रिफैक्टरिंग की आवश्यकता होती है, मैं इसके लिए नहीं जाऊंगा। यदि आप लाइब्रेरी डिज़ाइन नहीं कर रहे हैं, तो एनोटेशन जोड़ने से अधिक मूल्य प्रदान नहीं होता है, क्योंकि यदि आप लम्बाडा कार्यान्वयन करते हैं तो इंटरफ़ेस को एक गैर-कार्यात्मक में परिवर्तित करते हैं तो आप संकलन समस्याओं को तुरंत देखेंगे। –

उत्तर

6

reflections प्रोजेक्ट क्लासपाथ पर सभी कक्षाओं को ढूंढने और वापस करने में सक्षम है।

ReflectionUtils.forNames(new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner(false)) 
                    .addUrls(ClasspathHelper.forClassLoader())) 
         .getAllTypes()).stream() 
       .filter(Class::isInterface) 
       .collect(toMap(c -> c, 
           c -> Arrays.stream(c.getMethods()) 
             .filter(m -> !m.isDefault()) 
             .filter(m -> !Modifier.isStatic(m.getModifiers())) 
             .filter(m -> !isObjectMethod(m)) 
             .collect(toSet()))) 
       .entrySet().stream() 
       .filter(e -> e.getValue().size() == 1) 
       .sorted(comparing(e -> e.getKey().toString())) 
       .map(e -> e.getKey().toString() + " has single method " + e.getValue())//getOnlyElement(e.getValue())) 
       .forEachOrdered(System.out::println); 

isObjectMethod सहायक इस तरह परिभाषित किया गया है:

private static final Set<Method> OBJECT_METHODS = ImmutableSet.copyOf(Object.class.getMethods()); 
private static boolean isObjectMethod(Method m){ 
    return OBJECT_METHODS.stream() 
         .anyMatch(om -> m.getName().equals(om.getName()) && 
             m.getReturnType().equals(om.getReturnType()) && 
             Arrays.equals(m.getParameterTypes(), 
                 om.getParameterTypes())); 
} 

यह मदद नहीं करता है तुम वापस स्रोत कोड के लिए जाने के लिए और एनोटेशन जोड़ने, लेकिन यह आपको दे देंगे यहाँ एक काम कर उदाहरण दिया गया है से काम करने के लिए एक सूची।

+0

क्या होगा यदि इंटरफ़ेस 'ऑब्जेक्ट' की विधि को ओवरराइड करता है, जैसे 'तुलनाकर्ता' करता है? फिर, विधि को फ़िल्टर किया जाना चाहिए। और 'स्थिर 'विधियों को भी हटाया जाना चाहिए। या बेहतर, बस फिल्टर को 'अमूर्त' विधियों को पास करने दें। और 'धाराओं (स्प्लिटरेटर (c.getMethods(), 0), झूठी)' Arrays.stream (c.getMethods()) के बजाय 'का उपयोग करने का कोई कारण है? – Holger

+0

आपकी टिप्पणियों के साथ अपडेट किया गया –

+0

'.filter (m -> Modifier.isAbstract (m.getModifiers()) '' .filter (m ->! M.isDefault()) के बजाय 'फ़िल्टर (एम ->! Modifier.isStatic (m.getModifiers())) '? – Holger

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