2015-08-27 10 views
7

निम्न कार्य क्यों नहीं करते?जावा 8 किसी विशेष प्रकार के मनमानी ऑब्जेक्ट की उदाहरण विधि के लिए विधि संदर्भ

import java.util.function.Function; 

public class MethodRefTest { 
    public String passMeAround(String input) { 
     return input + " been passed to me"; 
    } 

    public Function<String, String> testReferences() { 
     final Function<String, String> f1 = MethodRefTest::passMeAround; 
     return f1; 
    } 

    public static void main(String[] args) { 
     new MethodRefTest() 
      .testReferences() 
      .apply("foo"); 
    } 
} 

javac मुझसे कहता है:

MethodRefTest.java:14: error: invalid method reference 
     final Function<String, String> f1 = MethodRefTest::passMeAround; 
             ^
    non-static method passMeAround(String) cannot be referenced from a static context 
1 error 

मैं समझ में नहीं आता क्यों संदर्भ स्थिर है। मैंने this पढ़ा लेकिन ऐसा लगता है कि यह समस्या का जवाब नहीं दे रहा है।

संपादित

इसके अलावा oracle के अनुसार, "एक विशेष प्रकार का एक मनमाना वस्तु का एक उदाहरण विधि के लिए संदर्भ" संभव के माध्यम से ContainingType::methodName

संपादित 2

@ मार्को-topolnik मदद की हैं मैं यहां अपनी गलती को समझता हूं। Function<String, String> f1 = MethodRefTest::passMeAround; , एक स्थिर विधि String MethodRefTest.passMeAround(String)

BiFunction<MethodRefTest, String, String> f1 = MethodRefTest::passMeAround; 
दूसरी ओर

को संदर्भित करता है any instance के कहने विधि को संदर्भित करता, जो लागू हों खंड में पारित हो जाता है।

BiFunction<MethodRefTest, String, String> f2 = MethodRefTest::passMeAround; 
//call instance method 
f2.apply(new MethodRefTest(), "some string"); 
+3

@ AlexandroSifuentesDíaz समय जावा 8 सीखने के लिए समय है। यह काफी समय से बाहर है। –

+2

खराब त्रुटि संदेश। – ZhongYu

+1

लेकिन @BrianGoetz, 'वर्ग :: विधि' (और ओपी के मामले में _does_) एक उदाहरण विधि संदर्भ को हल कर सकता है। त्रुटि संदेश भ्रामक है क्योंकि वास्तविक समस्या लक्ष्य प्रकार और आवृत्ति विधि संदर्भ के प्रकार के बीच मेल नहीं है। –

उत्तर

14

क्योंकि आप

MethodRefTest::passMeAround 

के रूप में यह करने के लिए भेजा आप

this::passMeAround 

के रूप में यह करने के लिए भेजा जाना चाहिए था संदर्भ के लिए उपयोग करने के लिए उदाहरण प्रदान करते हैं।

अपने वर्तमान कोड को देखने का एक अलग तरीका यह कहना है कि MethodRefTest::passMeAroundBiFunction<MethodRefTest, String, String> है और यह लैम्ब्डा आकार लक्ष्य साइट से मेल नहीं खाता है। तो, वैकल्पिक रूप से, आप

public BiFunction<MethodRefTest, String, String> testReferences() { 
    return MethodRefTest::passMeAround; 
} 

लिखा हो सकता है और मुख्य विधि

final MethodRefTest t = new MethodRefTest(); 
t.testReferences().apply(t, "foo"); 

सामग्री में आप पढ रहा हूं पर्याप्त शिक्षाप्रद नहीं हो सकता है, इसलिए मुझे विस्तार करते हैं।

this::passMeAround 

के साथ आप एक लैम्ब्डा वस्तु जो पर कब्जा कर लिया गया है संदर्भ में, जहां यह बनाया गया था से this उदाहरण मिलता है, लेकिन

MethodRefTest::passMeAround 

साथ आप एक "शुद्ध", गैर कब्जा लैम्ब्डा मिलता जो कुछ उदाहरण पर निर्दिष्ट विधि के आह्वान, के साथ कुछ स्ट्रिंग तर्क, इसलिए जब आप apply यह, आप दोनों में पारित करने के लिए की जरूरत है प्रतिनिधित्व करता है।

+0

मैं इस https://blog.idrsolutions.com/2015/02/java-8-method-references-explained-5-minutes/ उदाहरण का पालन कर रहा था। – dabai

+0

कुछ और स्पष्टीकरण http://www.studytrails.com/java/java8/Java8_Lambdas_FunctionalProgramming.jsp – cxw

0

बदलें passMeAround स्थिर करने के लिए:

public static String passMeAround(String input) { 
     return input + " been passed to me"; 
    } 

या उदाहरण विधि के लिए ही कहते हैं:

public Function<String, String> testReferences() { 
     final Function<String, String> f1 = this::passMeAround; 
     return f1; 
} 
+2

के "विधि संदर्भ" खंड में है "पास करने के लिए पास करें" स्थिर नहीं है और कुछ भी समझा नहीं है क्यों 'MethodRefTest :: passMeAround काम नहीं करता है? (ध्यान दें कि https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html 'ContainingType :: methodName' के अनुसार "किसी विशेष प्रकार की मनमानी वस्तु के * * विधि विधि * का संदर्भ है") – Pshemo

-1

क्यों संदर्भ स्थिर है के बारे में अपने प्रश्न का उत्तर करने के लिए, क्योंकि यह :: से पहले भाग उदाहरण के नाम के बजाय वर्ग का नाम था। यदि आपके पास कोई उदाहरण नहीं है, तो केवल स्थिर सदस्य ही पहुंच योग्य हैं।

+1

लेकिन 'MethodRefTest :: passMeAround' एक कानूनी विधि संदर्भ है, भले ही यह एक उदाहरण विधि को संदर्भित करता है। यह उस स्थान पर उचित नहीं है जहां ओपी ने इसका इस्तेमाल किया था। विधि संदर्भ सदस्य पहुंच अभिव्यक्ति नहीं है। –

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