- Method References
- Kinds of Method References
- Reference to a Static Method
- Reference to an Instance Method of a Particular Object
- Reference to an Instance Method of an Arbitrary Object of a Particular Type
- Reference to a Constructor
- Reference Variable in Java
- Java
- Java
- Java
- Java
- More on Reference Variable
- Class Reference
Method References
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
Consider again the Person class discussed in the section Lambda Expressions:
public class Person < // . LocalDate birthday; public int getAge() < // . >public LocalDate getBirthday() < return birthday; >public static int compareByAge(Person a, Person b) < return a.birthday.compareTo(b.birthday); >// . >
Suppose that the members of your social networking application are contained in an array, and you want to sort the array by age. You could use the following code (find the code excerpts described in this section in the example MethodReferencesTest ):
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]); class PersonAgeComparator implements Comparator < public int compare(Person a, Person b) < return a.getBirthday().compareTo(b.getBirthday()); >> Arrays.sort(rosterAsArray, new PersonAgeComparator());
The method signature of this invocation of sort is the following:
static void sort(T[] a, Comparator c)
Notice that the interface Comparator is a functional interface. Therefore, you could use a lambda expression instead of defining and then creating a new instance of a class that implements Comparator :
Arrays.sort(rosterAsArray, (Person a, Person b) -> < return a.getBirthday().compareTo(b.getBirthday()); >);
However, this method to compare the birth dates of two Person instances already exists as Person.compareByAge . You can invoke this method instead in the body of the lambda expression:
Arrays.sort(rosterAsArray, (a, b) -> Person.compareByAge(a, b) );
Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression:
Arrays.sort(rosterAsArray, Person::compareByAge);
The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b) . Each has the following characteristics:
- Its formal parameter list is copied from Comparator.compare , which is (Person, Person) .
- Its body calls the method Person.compareByAge .
Kinds of Method References
There are four kinds of method references:
Kind | Syntax | Examples |
---|---|---|
Reference to a static method | ContainingClass::staticMethodName | Person::compareByAge MethodReferencesExamples::appendStrings |
Reference to an instance method of a particular object | containingObject::instanceMethodName | myComparisonProvider::compareByName myApp::appendStrings2 |
Reference to an instance method of an arbitrary object of a particular type | ContainingType::methodName | String::compareToIgnoreCase String::concat |
Reference to a constructor | ClassName::new | HashSet::new |
The following example, MethodReferencesExamples , contains examples of the first three types of method references:
import java.util.function.BiFunction; public class MethodReferencesExamples < public static T mergeThings(T a, T b, BiFunction merger) < return merger.apply(a, b); >public static String appendStrings(String a, String b) < return a + b; >public String appendStrings2(String a, String b) < return a + b; >public static void main(String[] args) < MethodReferencesExamples myApp = new MethodReferencesExamples(); // Calling the method mergeThings with a lambda expression System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", (a, b) ->a + b)); // Reference to a static method System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", MethodReferencesExamples::appendStrings)); // Reference to an instance method of a particular object System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", myApp::appendStrings2)); // Reference to an instance method of an arbitrary object of a // particular type System.out.println(MethodReferencesExamples. mergeThings("Hello ", "World!", String::concat)); > >
All the System.out.println() statements print the same thing: Hello World!
BiFunction is one of many functional interfaces in the java.util.function package. The BiFunction functional interface can represent a lambda expression or method reference that accepts two arguments and produces a result.
Reference to a Static Method
The method references Person::compareByAge and MethodReferencesExamples::appendStrings are references to a static method.
Reference to an Instance Method of a Particular Object
The following is an example of a reference to an instance method of a particular object:
class ComparisonProvider < public int compareByName(Person a, Person b) < return a.getName().compareTo(b.getName()); >public int compareByAge(Person a, Person b) < return a.getBirthday().compareTo(b.getBirthday()); >> ComparisonProvider myComparisonProvider = new ComparisonProvider(); Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
The method reference myComparisonProvider::compareByName invokes the method compareByName that is part of the object myComparisonProvider . The JRE infers the method type arguments, which in this case are (Person, Person) .
Similarly, the method reference myApp::appendStrings2 invokes the method appendStrings2 that is part of the object myApp . The JRE infers the method type arguments, which in this case are (String, String) .
Reference to an Instance Method of an Arbitrary Object of a Particular Type
The following is an example of a reference to an instance method of an arbitrary object of a particular type:
String[] stringArray = < "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" >; Arrays.sort(stringArray, String::compareToIgnoreCase);
The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b) , where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b) .
Similarly, the method reference String::concat would invoke the method a.concat(b) .
Reference to a Constructor
You can reference a constructor in the same way as a static method by using the name new . The following method copies elements from one collection to another:
public static , DEST extends Collection> DEST transferElements( SOURCE sourceCollection, Supplier collectionFactory) < DEST result = collectionFactory.get(); for (T t : sourceCollection) < result.add(t); >return result; >
The functional interface Supplier contains one method get that takes no arguments and returns an object. Consequently, you can invoke the method transferElements with a lambda expression as follows:
Set rosterSetLambda = transferElements(roster, () -> < return new HashSet<>(); >);
You can use a constructor reference in place of the lambda expression as follows:
Set rosterSet = transferElements(roster, HashSet::new);
The Java compiler infers that you want to create a HashSet collection that contains elements of type Person . Alternatively, you can specify this as follows:
Set rosterSet = transferElements(roster, HashSet::new);
Previous page: Lambda Expressions
Next page: When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions
Reference Variable in Java
Before We Started with the Reference variable we should know about the following facts.
1. When we create an object (instance) of class then space is reserved in heap memory. Let’s understand with the help of an example.
Now, The space in the heap Memory is created but the question is how to access that space?.
Then, We create a Pointing element or simply called Reference variable which simply points out the Object(the created space in a Heap Memory).
Understanding Reference variable
1. Reference variable is used to point object/values.
2. Classes, interfaces, arrays, enumerations, and, annotations are reference types in Java. Reference variables hold the objects/values of reference types in Java.
3. Reference variable can also store null value. By default, if no object is passed to a reference variable then it will store a null value.
4. You can access object members using a reference variable using dot syntax.
Java
Let us see what is actually happening step by step.
1. When we create an object of demo class new DEMO();, the default constructor is called and returns a reference of the object, and simply this reference will be stored to the reference variable D1 (As we know that associativity is Right-hand side to left-hand side).
2. The value of a reference variable is a reference. When we attempt to print the value of a reference variable, the output contains the name of the class which has been instantiated concatenated by @ and the hash code created for it by Java: the string Demo@214c265e tells us that the given variable is of type Name and its hexadecimal format of hash code is 214c265e.
3. At this point we will access the methods display() of the class demo using our custom reference variable that we created.
BINDING UP : The constructor call returns a value that is a reference to the newly-created object. The equality sign tells the program that the value of the right-hand side expression is to be copied as the value of the variable on the left-hand side. The reference to the newly-created object, returned by the constructor call, is copied as the value of the variable.
Java
Java
Java
Note:
Here we pass G1 and Q1 reference variable point out the same object respectively. Secondly At Point 1 we try to get the value of the object with G1 reference variable which shows it as 25 and At Point 2 we try to get the value of an object with D1 reference variable which shows it as 25 as well. This will prove that the modification in the object can be done by using any reference variable but the condition is it should hold the same reference.
More on Reference Variable
1. Reference Variable as Method Parameters:
As the value of a primitive variable is directly stored in the variable, whereas the value of a reference variable holds a reference to an object. We also mentioned that assigning a value with the equality sign copies the value (possibly of some variable) on the right-hand side and stores it as the value of the left-hand-side variable. A similar kind of copying occurs during a method call. Regardless of whether the variable is primitive or reference type, a copy of the value is passed to the method’s argument and copied to that argument.
Note: Java only supports pass by value.
But we know that the reference variable holds the reference of an instance(OBJECT) so a copy of the reference is passed to the method’s argument.
Class Reference
Reference provides a way of recording address information about objects which themselves are not directly bound to the naming/directory system.
A Reference consists of an ordered list of addresses and class information about the object being referenced. Each address in the list identifies a communications endpoint for the same conceptual object. The «communications endpoint» is information that indicates how to contact the object. It could be, for example, a network address, a location in memory on the local machine, another process on the same machine, etc. The order of the addresses in the list may be of significance to object factories that interpret the reference.
Multiple addresses may arise for various reasons, such as replication or the object offering interfaces over more than one communication mechanism. The addresses are indexed starting with zero.
A Reference also contains information to assist in creating an instance of the object to which this Reference refers. It contains the class name of that object, and the class name and location of the factory to be used to create the object. The class factory location is a space-separated list of URLs representing the class path used to load the factory. When the factory class (or any class or resource upon which it depends) needs to be loaded, each URL is used (in order) to attempt to load the class.
A Reference instance is not synchronized against concurrent access by multiple threads. Threads that need to access a single Reference concurrently should synchronize amongst themselves and provide the necessary locking.