Anonymous Function in Java
A function defined as being unbound from an identifier is called an anonymous function. Because they permit access to variables within the scope of the contained function, these are a type of nested function (non-local functions). Therefore, closures must be used to implement anonymous functions. Lambda is only an anonymous function that may be passed around in an efficient manner.
An anonymous function is a definition as a function that is not associated with an identifier. Examples include function literals, lambda abstractions, lambda functions, and lambda expressions or blocks. For higher-order functions that need to return a function, anonymous functions are frequently utilized as inputs or to build the result.
An anonymous function is represented by a lambda expression, which also includes a function body, a set of arguments, and the lambda operator (->).
Return Type
The anonymous function's return type is the same as the body expression when there is only one statement.
The return type of an anonymous method is identical to the kind of result returned inside the code block when more than a statement is surrounded in curly brackets, or void when nothing is returned.
Examples
The following are some examples:
Zero parameter
() ->System.out.println(" No Parameters ");
one parameter
System.out.println("One parameter is: " + parameter); or
omitting the parentheses; parameter -> parameter (similar function example)
multiple parameters
(parameter1, parameter2) -> parameter1 + parameter2;
Types of Parameters
(int a, String name) ->System.out.println("id:" + (int a + a + "name:" + name);
Functional Interfaces
Let's assume that in our project we are able to identify all single-task APIs, or APIs with a single task to fulfill. like the Adder class in our programming language, which merely has to add two values and output the result. We, therefore, identify all such activities and make them accessible via a Java interface:
public interface AdderInterface {
int addNumbers(int a, int b);
}
And afterward, a class that implements it, like Adder, can do so. Such single-task interfaces do, however, have a specific place in Java, and since the release of JDK 8, their use has increased. We'll come to these eventually, but it's important to note that even JDK contains examples of single-tasked interfaces, such as java.lang.Runnable Interface.
Functional interfaces are what these interfaces are known as. Interfaces having just one abstract method included are said to be functional interfaces. And the "functionality" of this interface would be specified by this abstract method. The default methods stated with the standard keyword are non-abstract methods that can be found in a functional interface. In the event that the implementing class doesn't really offer any, these default methods give the interface's default implementations!
A functional interface can now be implemented in two different ways. The first step would be to develop a distinct class, like Adder, that would support the functional interface; alternatively, we might do so invisibly!
Anonymous Classes
Typically, anonymous classes implement interfaces or extend subclasses.
Type may be used here
- an anonymous class that extends a superclass
- a class that implements an anonymous interface
The code aforementioned dynamically constructs object1, an object of an anonymous class. An expression contains the definition of anonymous classes. Therefore, the semicolon is used to denote the end of the expression at the end of unnamed classes.
Recall that we mentioned the dynamic languages issue; to avoid it, we might implement the interface in an anonymous manner.
AdderInterfaceaddrInterface= newAdderInterface ()
{
Public int addNumbers (int a,int b){
return a+b;
}
};
Now that this addrInterface contains an anonymous representation of the initial AdderInterface, it may be used just like a conventional AdderInterface implementation with a named implementation! Be aware that we did not develop a concrete class that implements the AdderInterface interface in the aforementioned implementation. By implementing this, we have already significantly lessened boilerplate and verbosity.
There are also finer distinctions to be made in addition to the reduced boilerplate and verbosity, though. Take a look at the anonymous approach once more, but this time with the exception of the fact that it is now contained within a class with its own member var, let's say outer, and the anonymous approach also has a state - inner:
class Encapsulator{
int outer = 50;
AdderInterfaceaddrInterface = new AdderInterface(){
int inner = 30;
public int addNumbers (int a, int b){
int in = this.inner;
Encapsulator.this.outer
return a+b;
}
};
}
While the instance variables inner is available within the anonymous implementation of the addNumbers(...)method, the instance variable outer, which is a member of the enclosing class, is not. Instead, we must use the following construct to access outer within the anonymous implementation: Encapsulator.this.outer
Example 1
class Polygon {
public void display() {
System.out.println("Inside the Polygon class");
}
}
class AnonymousDemo {
public void createClass() {
Polygon p1 = new Polygon() {
public void display() {
System.out.println("Inside an anonymous class.");
}
};
p1.display();
}
}
class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
The output of the above program
Inside an anonymous class.
Example 2
interface Polygon {
public void display();
}
class AnonymousDemo {
public void createClass() {
Polygon p1 = new Polygon() {
public void display() {
System.out.println("Inside an anonymous class.");
}
};
p1.display();
}
}
class Main {
public static void main(String[] args) {
AnonymousDemo an = new AnonymousDemo();
an.createClass();
}
}
The output of the above program
Inside an anonymous class.
Benefits of Anonymized Classes
Whenever they are needed, objects are created in anonymous classes. In other words, objects are made to carry out some specific functions. For instance,
Object = new Example() {
public void display() {
System.out.println("Anonymous class overrides the method display().");
}
}
When we want to override its display() method, in this case, a dynamically constructed object of an anonymous class is created.
We can write cleaner code by using anonymous classes.