::
विधि संदर्भ कहा जाता है। यह मूल रूप से एकल विधि का संदर्भ है। यानी यह नाम से मौजूदा पद्धति को संदर्भित करता है।
लघु स्पष्टीकरण :
नीचे एक स्थिर विधि के संदर्भ का एक उदाहरण है:
class Hey {
public static double square(double num){
return Math.pow(num, 2);
}
}
Function<Double, Double> square = Hey::square;
double ans = square.apply(23d);
square
ऑब्जेक्ट रेफरेंस की तरह ही पास हो सकता है और जरूरत पड़ने पर ट्रिगर हो सकता है। वास्तव में, यह वस्तुओं के "सामान्य" तरीकों के संदर्भ के रूप में आसानी से उपयोग किया जा सकता static
है। उदाहरण के लिए:
class Hey {
public double square(double num) {
return Math.pow(num, 2);
}
}
Hey hey = new Hey();
Function<Double, Double> square = hey::square;
double ans = square.apply(23d);
Function
ऊपर एक कार्यात्मक इंटरफ़ेस है । पूरी तरह से समझने के लिए ::
, कार्यात्मक इंटरफेस को भी समझना महत्वपूर्ण है। पूरी तरह से, एक कार्यात्मक इंटरफ़ेस सिर्फ एक सार पद्धति वाला एक इंटरफ़ेस है।
कार्यात्मक इंटरफेस के उदाहरणों में शामिल Runnable
, Callable
, और ActionListener
।
Function
ऊपर सिर्फ एक विधि के साथ एक कार्यात्मक इंटरफ़ेस है apply
:। यह एक तर्क लेता है और एक परिणाम उत्पन्न करता है।
कारण यह ::
है कि भयानक हैं :
मेथड रेफरेंस ऐसे एक्सप्रेशन होते हैं जिनका लैम्बडा एक्सप्रेशन (...) के समान उपचार होता है, लेकिन वे एक मेथड बॉडी प्रदान करने के बजाय, मौजूदा विधि को नाम से संदर्भित करते हैं।
जैसे कि मेमने का शरीर लिखने के बजाय
Function<Double, Double> square = (Double x) -> x * x;
आप बस कर सकते हैं
Function<Double, Double> square = Hey::square;
रनटाइम के दौरान, ये दो square
विधियां बिल्कुल एक-दूसरे के समान व्यवहार करती हैं। बाईटेकोड समान हो सकता है या नहीं (हालांकि, उपरोक्त मामले के लिए, एक ही बायटेकोड उत्पन्न होता है, ऊपर संकलित करें और साथ जांचें javap -c
)।
संतुष्ट करने के लिए एकमात्र मुख्य मानदंड है: आपके द्वारा प्रदान की जाने वाली विधि में ऑब्जेक्ट संदर्भ के रूप में आपके द्वारा उपयोग किए जाने वाले कार्यात्मक इंटरफ़ेस की विधि के समान हस्ताक्षर होना चाहिए ।
नीचे अवैध है:
Supplier<Boolean> p = Hey::square; // illegal
square
एक तर्क की उम्मीद करता है और एक रिटर्न देता है double
। get
में विधि प्रदायक एक मान देता है लेकिन एक तर्क नहीं लेता है। इस प्रकार, यह एक त्रुटि का परिणाम है।
एक विधि संदर्भ एक कार्यात्मक इंटरफ़ेस की विधि को संदर्भित करता है। (जैसा कि उल्लेख किया गया है, कार्यात्मक इंटरफेस में केवल एक ही विधि हो सकती है)।
कुछ और उदाहरण: उपभोक्ता का accept
तरीका एक इनपुट लेता है, लेकिन कुछ भी वापस नहीं करता है।
Consumer<Integer> b1 = System::exit; // void exit(int status)
Consumer<String[]> b2 = Arrays::sort; // void sort(Object[] a)
Consumer<String> b3 = MyProgram::main; // void main(String... args)
class Hey {
public double getRandom() {
return Math.random();
}
}
Callable<Double> call = hey::getRandom;
Supplier<Double> call2 = hey::getRandom;
DoubleSupplier sup = hey::getRandom;
// Supplier is functional interface that takes no argument and gives a result
ऊपर, getRandom
कोई तर्क नहीं लेता है और एक रिटर्न देता है double
। तो कोई भी कार्यात्मक इंटरफ़ेस जो मानदंड को संतुष्ट करता है: कोई तर्क नहीं लेता है और वापसीdouble
का उपयोग किया जा सकता है।
एक और उदाहरण:
Set<String> set = new HashSet<>();
set.addAll(Arrays.asList("leo","bale","hanks"));
Predicate<String> pred = set::contains;
boolean exists = pred.test("leo");
पैरामीटर किए गए प्रकारों के मामले में :
class Param<T> {
T elem;
public T get() {
return elem;
}
public void set(T elem) {
this.elem = elem;
}
public static <E> E returnSame(E elem) {
return elem;
}
}
Supplier<Param<Integer>> obj = Param<Integer>::new;
Param<Integer> param = obj.get();
Consumer<Integer> c = param::set;
Supplier<Integer> s = param::get;
Function<String, String> func = Param::<String>returnSame;
विधि संदर्भों की अलग-अलग शैलियाँ हो सकती हैं, लेकिन मूल रूप से इन सभी का मतलब एक ही है और इसे केवल लंबोदर के रूप में देखा जा सकता है:
- एक स्थिर विधि (
ClassName::methName
)
- किसी विशेष वस्तु की एक आवृत्ति विधि (
instanceRef::methName
)
- किसी विशेष वस्तु की एक सुपर विधि (
super::methName
)
- किसी विशेष प्रकार की मनमानी वस्तु का एक उदाहरण विधि (
ClassName::methName
)
- एक क्लास कंस्ट्रक्टर संदर्भ (
ClassName::new
)
- एक सरणी निर्माता संदर्भ (
TypeName[]::new
)
अधिक संदर्भ के लिए, http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html देखें ।