Java Method References and Functional Interfaces

Last updated on Dec 26 2022
Prabhas Ramanathan

Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference. In this section, we are explaining method reference concept in detail.

Table of Contents

Types of Method References

There are following types of method references in java:
1. Reference to a static method.
2. Reference to an instance method.
3. Reference to a constructor.

java 80

1) Reference to a Static Method

You can refer to static method defined in the class. Following is the syntax and example which describe the process of referring static method in Java.
Syntax
1. ContainingClass::staticMethodName

Example 1

In the following example, we have defined a functional interface and referring a static method to it’s functional method say().

1. interface Sayable{ 
2. void say(); 
3. } 
4. public class MethodReference { 
5. public static void saySomething(){ 
6. System.out.println("Hello, this is static method."); 
7. } 
8. public static void main(String[] args) { 
9. // Referring static method 
10. Sayable sayable = MethodReference::saySomething; 
11. // Calling interface method 
12. sayable.say(); 
13. } 
14. }

Test it Now
Output:
Hello, this is static method.

Example 2

In the following example, we are using predefined functional interface Runnable to refer static method.

1. public class MethodReference2 { 
2. public static void ThreadStatus(){ 
3. System.out.println("Thread is running..."); 
4. } 
5. public static void main(String[] args) { 
6. Thread t2=new Thread(MethodReference2::ThreadStatus); 
7. t2.start(); 
8. } 
9. }

Test it Now
Output:
Thread is running…

Example 3

You can also use predefined functional interface to refer methods. In the following example, we are using BiFunction interface and using it’s apply() method.

1. import java.util.function.BiFunction; 
2. class Arithmetic{ 
3. public static int add(int a, int b){ 
4. return a+b; 
5. } 
6. } 
7. public class MethodReference3 { 
8. public static void main(String[] args) { 
9. BiFunction<Integer, Integer, Integer>adder = Arithmetic::add; 
10. int result = adder.apply(10, 20); 
11. System.out.println(result); 
12. } 
13. }

Test it Now
Output:
30

 

Example 4

You can also override static methods by referring methods. In the following example, we have defined and overloaded three add methods.

1. import java.util.function.BiFunction; 
2. class Arithmetic{ 
3. public static int add(int a, int b){ 
4. return a+b; 
5. } 
6. public static float add(int a, float b){ 
7. return a+b; 
8. } 
9. public static float add(float a, float b){ 
10. return a+b; 
11. } 
12. } 
13. public class MethodReference4 { 
14. public static void main(String[] args) { 
15. BiFunction<Integer, Integer, Integer>adder1 = Arithmetic::add; 
16. BiFunction<Integer, Float, Float>adder2 = Arithmetic::add; 
17. BiFunction<Float, Float, Float>adder3 = Arithmetic::add; 
18. int result1 = adder1.apply(10, 20); 
19. float result2 = adder2.apply(10, 20.0f); 
20. float result3 = adder3.apply(10.0f, 20.0f); 
21. System.out.println(result1); 
22. System.out.println(result2); 
23. System.out.println(result3); 
24. } 
25. }

Test it Now
Output:
30
30.0
30.0

2) Reference to an Instance Method

like static methods, you can refer instance methods also. In the following example, we are describing the process of referring the instance method.

Syntax
1. containingObject::instanceMethodName

Example 1

In the following example, we are referring non-static methods. You can refer methods by class object and anonymous object.

1. interface Sayable{ 
2. void say(); 
3. } 
4. public class InstanceMethodReference { 
5. public void saySomething(){ 
6. System.out.println("Hello, this is non-static method."); 
7. } 
8. public static void main(String[] args) { 
9. InstanceMethodReference methodReference = new InstanceMethodReference(); // Creating object 
10. // Referring non-static method using reference 
11. Sayable sayable = methodReference::saySomething; 
12. // Calling interface method 
13. sayable.say(); 
14. // Referring non-static method using anonymous object 
15. Sayable sayable2 = new InstanceMethodReference()::saySomething; // You can use anonymous object also 
16. // Calling interface method 
17. sayable2.say(); 
18. } 
19. }

Test it Now
Output:

Hello, this is non-static method.
Hello, this is non-static method.

 

Example 2

In the following example, we are referring instance (non-static) method. Runnable interface contains only one abstract method. So, we can use it as functional interface.

1. public class InstanceMethodReference2 { 
2. public void printnMsg(){ 
3. System.out.println("Hello, this is instance method"); 
4. } 
5. public static void main(String[] args) { 
6. Thread t2=new Thread(new InstanceMethodReference2()::printnMsg); 
7. t2.start(); 
8. } 
9. }

Test it Now
Output:

Hello, this is instance method

 

Example 3

In the following example, we are using BiFunction interface. It is a predefined interface and contains a functional method apply(). Here, we are referring add method to apply method.

1. import java.util.function.BiFunction; 
2. class Arithmetic{ 
3. public int add(int a, int b){ 
4. return a+b; 
5. } 
6. } 
7. public class InstanceMethodReference3 { 
8. public static void main(String[] args) { 
9. BiFunction<Integer, Integer, Integer>adder = new Arithmetic()::add; 
10. int result = adder.apply(10, 20); 
11. System.out.println(result); 
12. } 
13. }

Test it Now
Output:
30

 

3) Reference to a Constructor

You can refer a constructor by using the new keyword. Here, we are referring constructor with the help of functional interface.

Syntax
1. ClassName::new

Example

1. interface Messageable{ 
2. Message getMessage(String msg); 
3. } 
4. class Message{ 
5. Message(String msg){ 
6. System.out.print(msg); 
7. } 
8. } 
9. public class ConstructorReference { 
10. public static void main(String[] args) { 
11. Messageable hello = Message::new; 
12. hello.getMessage("Hello"); 
13. } 
14. }

Test it Now
Output:
Hello

Java Functional Interfaces

An Interface that contains exactly one abstract method is known as functional interface. It can have any number of default, static methods but can contain only one abstract method. It can also declare methods of object class.
Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces. It is a new feature in Java, which helps to achieve functional programming approach.

Example 1

1. @FunctionalInterface 
2. interface sayable{ 
3. void say(String msg); 
4. } 
5. public class FunctionalInterfaceExample implements sayable{ 
6. public void say(String msg){ 
7. System.out.println(msg); 
8. } 
9. public static void main(String[] args) { 
10. FunctionalInterfaceExample fie = new FunctionalInterfaceExample(); 
11. fie.say("Hello there"); 
12. } 
13. }

Test it Now
Output:
Hello there

 

A functional interface can have methods of object class. See in the following example.

Example 2

1. 
2. @FunctionalInterface 
3. interface sayable{ 
4. void say(String msg); // abstract method 
5. // It can contain any number of Object class methods. 
6. int hashCode(); 
7. String toString(); 
8. boolean equals(Object obj); 
9. } 
10. public class FunctionalInterfaceExample2 implements sayable{ 
11. public void say(String msg){ 
12. System.out.println(msg); 
13. } 
14. public static void main(String[] args) { 
15. FunctionalInterfaceExample2 fie = new FunctionalInterfaceExample2(); 
16. fie.say("Hello there"); 
17. } 
18. }

Test it Now
Output:
Hello there

 

Invalid Functional Interface

A functional interface can extends another interface only when it does not have any abstract method.

1. interface sayable{ 
2. void say(String msg); // abstract method 
3. } 
4. @FunctionalInterface 
5. interface Doable extends sayable{ 
6. // Invalid '@FunctionalInterface' annotation; Doable is not a functional interface 
7. void doIt(); 
8. }

Output:
compile-time error

 

Example 3

In the following example, a functional interface is extending to a non-functional interface.

1. interface Doable{ 
2. default void doIt(){ 
3. System.out.println("Do it now"); 
4. } 
5. } 
6. @FunctionalInterface 
7. interface Sayable extends Doable{ 
8. void say(String msg); // abstract method 
9. } 
10. public class FunctionalInterfaceExample3 implements Sayable{ 
11. public void say(String msg){ 
12. System.out.println(msg); 
13. } 
14. public static void main(String[] args) { 
15. FunctionalInterfaceExample3 fie = new FunctionalInterfaceExample3(); 
16. fie.say("Hello there"); 
17. fie.doIt(); 
18. } 
19. }

Test it Now
Output:
Hello there

Do it now

Java Predefined-Functional Interfaces

Java provides predefined functional interfaces to deal with functional programming by using lambda and method references.
You can also define your own custom functional interface. Following is the list of functional interface which are placed in java.util.function package.

Interface Description
BiConsumer<T,U> It represents an operation that accepts two input arguments and returns no result.
Consumer<T> It represents an operation that accepts a single argument and returns no result.
Function<T,R> It represents a function that accepts one argument and returns a result.
Predicate<T> It represents a predicate (boolean-valued function) of one argument.
BiFunction<T,U,R> It represents a function that accepts two arguments and returns a a result.
BinaryOperator<T> It represents an operation upon two operands of the same data type. It returns a result of the same type as the operands.
BiPredicate<T,U> It represents a predicate (boolean-valued function) of two arguments.
BooleanSupplier It represents a supplier of boolean-valued results.
DoubleBinaryOperator It represents an operation upon two double type operands and returns a double type value.
DoubleConsumer It represents an operation that accepts a single double type argument and returns no result.
DoubleFunction<R> It represents a function that accepts a double type argument and produces a result.
DoublePredicate It represents a predicate (boolean-valued function) of one double type argument.
DoubleSupplier It represents a supplier of double type results.
DoubleToIntFunction It represents a function that accepts a double type argument and produces an int type result.
DoubleToLongFunction It represents a function that accepts a double type argument and produces a long type result.
DoubleUnaryOperator It represents an operation on a single double type operand that produces a double type result.
IntBinaryOperator It represents an operation upon two int type operands and returns an int type result.
IntConsumer It represents an operation that accepts a single integer argument and returns no result.
IntFunction<R> It represents a function that accepts an integer argument and returns a result.
IntPredicate It represents a predicate (boolean-valued function) of one integer argument.
IntSupplier It represents a supplier of integer type.
IntToDoubleFunction It represents a function that accepts an integer argument and returns a double.
IntToLongFunction It represents a function that accepts an integer argument and returns a long.
IntUnaryOperator It represents an operation on a single integer operand that produces an integer result.
LongBinaryOperator It represents an operation upon two long type operands and returns a long type result.
LongConsumer It represents an operation that accepts a single long type argument and returns no result.
LongFunction<R> It represents a function that accepts a long type argument and returns a result.
LongPredicate It represents a predicate (boolean-valued function) of one long type argument.
LongSupplier It represents a supplier of long type results.
LongToDoubleFunction It represents a function that accepts a long type argument and returns a result of double type.
LongToIntFunction It represents a function that accepts a long type argument and returns an integer result.
LongUnaryOperator It represents an operation on a single long type operand that returns a long type result.
ObjDoubleConsumer<T> It represents an operation that accepts an object and a double argument, and returns no result.
ObjIntConsumer<T> It represents an operation that accepts an object and an integer argument. It does not return result.
ObjLongConsumer<T> It represents an operation that accepts an object and a long argument, it returns no result.
Supplier<T> It represents a supplier of results.
ToDoubleBiFunction<T,U> It represents a function that accepts two arguments and produces a double type result.
ToDoubleFunction<T> It represents a function that returns a double type result.
ToIntBiFunction<T,U> It represents a function that accepts two arguments and returns an integer.
ToIntFunction<T> It represents a function that returns an integer.
ToLongBiFunction<T,U> It represents a function that accepts two arguments and returns a result of long type.
ToLongFunction<T> It represents a function that returns a result of long type.
UnaryOperator<T> It represents an operation on a single operand that returnsa a result of the same type as its operand.

So, this brings us to the end of blog. This Tecklearn ‘Java Method References and Functional Interfaces’ blog helps you with commonly asked questions if you are looking out for a job in Java Programming. If you wish to learn Java and build a career Java Programming domain, then check out our interactive, Java and JEE Training, that comes with 24*7 support to guide you throughout your learning period. Please find the link for course details:

Java and JEE Training

Java and JEE Training

About the Course

Java and JEE Certification Training is designed by professionals as per the industrial requirements and demands. This training encompasses comprehensive knowledge on basic and advanced concepts of core Java & J2EE along with popular frameworks like Hibernate, Spring & SOA. In this course, you will gain expertise in concepts like Java Array, Java OOPs, Java Function, Java Loops, Java Collections, Java Thread, Java Servlet, and Web Services using industry use-cases and this will help you to become a certified Java expert.

Why Should you take Java and JEE Training?

• Java developers are in great demand in the job market. With average pay going between $90,000/- to $120,000/- depending on your experience and the employers.
• Used by more than 10 Million developers worldwide to develop applications for 15 Billion devices.
• Java is one of the most popular programming languages in the software world. Rated #1 in TIOBE Popular programming languages index (15th Consecutive Year)

What you will Learn in this Course?

Introduction to Java

• Java Fundamentals
• Introduction to Java Basics
• Features of Java
• Various components of Java language
• Benefits of Java over other programming languages
• Key Benefits of Java

Installation and IDE’s for Java Programming Language

• Installation of Java
• Setting up of Eclipse IDE
• Components of Java Program
• Editors and IDEs used for Java Programming
• Writing a Simple Java Program

Data Handling and Functions

• Data types, Operations, Compilation process, Class files, Loops, Conditions
• Using Loop Constructs
• Arrays- Single Dimensional and Multi-Dimensional
• Functions
• Functions with Arguments

OOPS in Java: Concept of Object Orientation

• Object Oriented Programming in Java
• Implement classes and objects in Java
• Create Class Constructors
• Overload Constructors
• Inheritance
• Inherit Classes and create sub-classes
• Implement abstract classes and methods
• Use static keyword
• Implement Interfaces and use it

Polymorphism, Packages and String Handling

• Concept of Static and Run time Polymorphism
• Function Overloading
• String Handling –String Class
• Java Packages

Exception Handling and Multi-Threading

• Exception handling
• Various Types of Exception Handling
• Introduction to multi-threading in Java
• Extending the thread class
• Synchronizing the thread

File Handling in Java

• Input Output Streams
• Java.io Package
• File Handling in Java

Java Collections

• Wrapper Classes and Inner Classes: Integer, Character, Boolean, Float etc
• Applet Programs: How to write UI programs with Applet, Java.lang, Java.io, Java.util
• Collections: ArrayList, Vector, HashSet, TreeSet, HashMap, HashTable

Java Database Connectivity (JDBC)

• Introduction to SQL: Connect, Insert, Update, Delete, Select
• Introduction to JDBC and Architecture of JDBC
• Insert/Update/Delete/Select Operations using JDBC
• Batch Processing Transaction
• Management: Commit and Rollback

Java Enterprise Edition – Servlets

• Introduction to J2EE
• Client Server architecture
• URL, Port Number, Request, Response
• Need for servlets
• Servlet fundamentals
• Setting up a web project in Eclipse
• Configuring and running the web app with servlets
• GET and POST request in web application with demo
• Servlet lifecycle
• Servlets Continued
• Session tracking and filter
• Forward and include Servlet request dispatchers

Java Server Pages (JSP)

• Fundamentals of Java Server Page
• Writing a code using JSP
• The architecture of JSP
• JSP Continued
• JSP elements: Scriptlets, expressions, declaration
• JSP standard actions
• JSP directives
• Introduction to JavaBeans
• ServletConfig and ServletContext
• Servlet Chaining
• Cookies Management
• Session Management

Hibernate

• Introduction to Hibernate
• Introduction to ORM
• ORM features
• Hibernate as an ORM framework
• Hibernate features
• Setting up a project with Hibernate framework
• Basic APIs needed to do CRUD operations with Hibernate
• Hibernate Architecture

POJO (Plain Old Java Object)

• POJO (Plain Old Java Object)
• Persistent Objects
• Lifecycle of Persistent Object

Spring

• Introduction to Spring
• Spring Fundamentals
• Advanced Spring

Got a question for us? Please mention it in the comments section and we will get back to you.

 

 

0 responses on "Java Method References and Functional Interfaces"

Leave a Message

Your email address will not be published. Required fields are marked *