Java Tutorial
Operators
Flow Control
String
Number and Date
Built-in Classes
Array
Class and Object
Inheritance and Polymorphism
Exception Handling
Collections, Generics and Enumerations
Reflection
Input/Output Stream
Annotation
In Java, functional interfaces were introduced in Java 8 as a way to support lambda expressions and method references. A functional interface is an interface that has only one abstract method, excluding the default and static methods. The @FunctionalInterface
annotation is used to indicate that an interface is intended to be a functional interface. In this tutorial, we'll discuss the basics of the @FunctionalInterface
annotation and its usage.
To create a functional interface, simply define an interface with a single abstract method and use the @FunctionalInterface
annotation. The annotation is optional but recommended, as it ensures that the interface will have only one abstract method, and any attempts to add more will result in a compile-time error.
Example:
@FunctionalInterface public interface MyFunction { int apply(int x, int y); }
In this example, we have created a functional interface called MyFunction
with a single abstract method apply
.
Functional interfaces can be used as targets for lambda expressions, which are a concise way to represent instances of functional interfaces.
Example:
public class LambdaExample { public static void main(String[] args) { MyFunction add = (x, y) -> x + y; MyFunction multiply = (x, y) -> x * y; System.out.println("Add: " + add.apply(5, 3)); System.out.println("Multiply: " + multiply.apply(5, 3)); } }
In this example, we create two instances of the MyFunction
functional interface using lambda expressions. The add
instance adds two numbers, and the multiply
instance multiplies them.
Method references provide another way to create instances of functional interfaces. They are used to refer to methods of existing classes or objects.
Example:
public class MethodReferenceExample { public static void main(String[] args) { MyFunction add = Integer::sum; MyFunction multiply = MethodReferenceExample::multiply; System.out.println("Add: " + add.apply(5, 3)); System.out.println("Multiply: " + multiply.apply(5, 3)); } public static int multiply(int x, int y) { return x * y; } }
In this example, we create two instances of the MyFunction
functional interface using method references. The add
instance refers to the Integer.sum
method, and the multiply
instance refers to the multiply
method of the MethodReferenceExample
class.
In conclusion, the @FunctionalInterface
annotation is used to indicate that an interface is intended to be a functional interface with a single abstract method. Functional interfaces enable the use of lambda expressions and method references, which provide more concise and readable ways to represent instances of functional interfaces.
Creating functional interfaces in Java
A functional interface is an interface with only one abstract method. You can create one like this:
@FunctionalInterface public interface MyFunctionalInterface { void myMethod(); }
Single Abstract Method (SAM) and @FunctionalInterface in Java
A functional interface has a Single Abstract Method (SAM), and the @FunctionalInterface
annotation ensures that it adheres to this rule.
@FunctionalInterface public interface MyFunctionalInterface { void myMethod(); }
Functional interfaces in Java 8 and beyond
Java 8 introduced the concept of functional interfaces, paving the way for the use of lambda expressions.
@FunctionalInterface public interface MyFunctionalInterface { void myMethod(); }
Lambda expressions and @FunctionalInterface
Lambda expressions allow concise implementation of functional interfaces.
MyFunctionalInterface myFunc = () -> System.out.println("My Method Implementation"); myFunc.myMethod();
Java built-in functional interfaces
Java provides built-in functional interfaces in the java.util.function
package, such as Predicate
, Function
, Consumer
, and Supplier
.
// Example using Predicate Predicate<Integer> isEven = num -> num % 2 == 0; System.out.println(isEven.test(4)); // Outputs: true
Defining custom functional interfaces in Java
You can create your own custom functional interfaces based on specific requirements.
@FunctionalInterface public interface Calculator { int operate(int a, int b); }
Role of @FunctionalInterface in Java Streams API
Functional interfaces play a significant role in the Java Streams API, enabling concise and expressive stream operations.
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange"); fruits.stream() .filter(fruit -> fruit.startsWith("A")) .forEach(System.out::println);
Checking for functional interface with @FunctionalInterface
The @FunctionalInterface
annotation ensures that an interface has only one abstract method.
@FunctionalInterface public interface MyFunctionalInterface { void myMethod(); default void anotherMethod() { System.out.println("Another method"); } }
The compiler would generate an error for the above interface because it contains more than one abstract method.