Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I know a functional interface means you can have exactly/only 1 abstract method with more than 1 default method(s) but I am wondering how to relate to it with a real-world example/situation of using a functional interface in Java.
Could you give a valid situation/example?
Thanks in advance!
First of all annotation #FunctionalInterface is used by Java's built-in functional interfaces Predicate,Function,Consumer, etc...
From the other hand you may want to create your custom one like the following:
#FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws CustomException;
}
Then you can use it as a method parameter:
public <T, R> void doSomething(T value, ThrowingConsumer<T, R> consumer) {
// ...
}
And then call it like this:
doSomething(someValue, this::customConsumerMethodThrowingAnException);
It is worth to mention that #FunctionalInterface is not required. The compiler will be perfectly fine with any interface meeting the requirements.
The compiler treats it in a way similar to dealing with #Override annotation. The code compiles even without it. But once added it makes the code clearer and safer for the ones who will maintain the code in the future.
We've always had functional interfaces before JDK8 but no lambdas, method references etc.
As of JDK8, they provide a target type for lambda expressions, method references and in turn, have better readability and more compact code.
Example, prior to Java-8 if you wanted to provide some logic that will be executed each time a Button component is clicked you'd do:
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
This is bulky, hard to read and not compact enough. because EventHandler is by definition a functional interface i.e. it has a SAM as of jdk8 you can now do:
btn.setOnAction(event -> System.out.println("Hello World!"));
You only see the part of the code you care about i.e. the logic to be executed when the button is clicked.
Further, due to the fact that we can use functional interfaces as target types for lambda expressions & methods references, this would be useful when:
passing a comparator to a sort method e.g. List.sort, Stream.sorted, Collections.sort etc.
passing a block of code to run a task in a separate thread
etc...
while keeping the code readable, compact and concise.
Functional interfaces are used extensively in the Java-stream API.
There's no reason for you to create your own functional interface except there's not one that meets your requirements from java.util.function or the name of the functional interface is not as readable so thus you may create your own.
There's also a #FunctionalInterface annotation recommended to be used but not required whenever you're creating a functional interface (the standard library uses this a lot).
This enables the compiler to check that the annotated entity is an interface with a single abstract method otherwise gives an error.
This is also quite helpful in being able to catch errors when refactoring your code.
One of the primary use that they've provided is that the instances of functional interfaces can be created with lambda expressions and method references as well as using a constructor at the same time. For example, a functional interface Sample defined as:
#FunctionalInterface
public interface Sample {
void ab();
}
can be instantiated in as simple as a single line of code as :
Sample sample = () -> System.out.println("ab called");
and then called wherever required as:
sample.ab();
I would further quote the Javadoc from the java.util.function package:
Functional interfaces can provide a target type in multiple contexts,
such as assignment context, method invocation, or cast context:
// Assignment context
Predicate<String> p = String::isEmpty;
// Method invocation context
stream.filter(e -> e.getSize() > 10)...
// Cast context
stream.map((ToIntFunction) e -> e.getSize())...
Furthermore, such interfaces could be annotated with #FunctionalInterface annotation.
This annotation is not a requirement for the compiler to recognize
an interface as a functional interface, but merely an aid to capture
design intent and enlist the help of the compiler in identifying
accidental violations of design intent.
Also a worthy point for using the concepts with existing such interfaces,
the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.
Interfaces which are marked with FunctionalInterface are guaranteed to be applicable in contexts where a lambda expression with appropriate parameter and return types is expected. Besides that, they have no usage. There might be some optimizations, but in all cases it doesnt matter
Lambdas are implementations of Functional interface...so either implicitly (by a compiler or at run-time) or explicitly (by code...assignment) they are going to be used. Practical example is
Predicate : usage across code for filtering.
Functions : Map.computeIfAbsent("xxx", s -> s.length());
BiFunction : salaries.replaceAll((name, oldValue) -> name.equals("Freddy") ? oldValue : oldValue + 10000);
Consumers : List.forEach(name -> System.out.println("Hello, " + name));
Related
This question already has answers here:
What are functional interfaces used for in Java 8?
(11 answers)
Closed 3 years ago.
Recently I started in a new project where all the interfaces with a single abstract method are anotated with #FunctionalInterface. Constantly I see people removing the annotation after adding another abstract method in the interface. When did I ask why? They told me that someone that isn't in the company anymore told them to do it like that. Now I'm not sure if it's a good idea to annotate interfaces that obviously will not be used with lambdas.
Now I see that a piece of useful information is that people are using the anotation even in services in services. I just seemed a code like:
#FunctionalInterface
public interface SomeService {
void doSomething();
}
I'm not sure if it's a good idea to annotate interfaces that obviously
will not be used with lambdas
It's not. At best, it's a waste of time. At worst, it's actively misleading.
The documentation says
[Use to indicate that the type] is intended to be a functional interface
If you say it will "obviously not" be used in a lambda then using a annotation that marks that you do expect that usage is a clear contradiction.
Explanation
Every interface that only offers one (abstract) method, i.e. without implementation, is a so called functional interface.
Being it explicitly or implicitly.
The annotation #FunctionalInterface is, like #Override, optional, if you want to create a functional interface.
So if you declare an interface #FunctionalInterface, but it actually has more than just one such method, the compiler helps you and prevents compilation with an error. Telling you that you violated your own intention.
If you do not have the annotation, it will compile, but it is not a functional interface anymore. This could be a bug to you, because your intention was to create a functional interface. Note that if you are actually using the interface in an environment where a functional interface is actually required, like for a lambda, it would obviously not compile anymore as soon as another method is added to the interface.
Here are some examples:
// is a functional interface
interface Foo {
void bar();
}
// is a functional interface
#FunctionalInterface
interface Foo {
void bar();
}
// is not a functional interface
interface Foo {
void bar();
void baz();
}
// does not compile
#FunctionalInterface
interface Foo {
void bar();
void baz();
}
Use
It is to make your intention clear to the compiler, other team members and your future self. That way, the compiler can help you spot bugs in case you mess up.
Another scenario might be if you are working in a team and design an interface. If you do not clearly mark this interface as functional interface, either by the annotation or with a comment/documentation, another team member might not know your intention and add more methods to it.
This is especially important if you are a library designer, i.e. writing code that is to be used by other, external, people. If you mark your interface #FunctionalInterface, it is a promise to them that you intent to keep it like that. So they can safely use it for lambdas, for example. Without fearing that their code will break as soon as you ship an update to your library.
The opposite case is true as well. If they spot an interface of yours that only has one method, but is not explicitly annotated, they will understand that this is not meant to be used as functional interface, eventhough it currently is one. Thus, they will not use it for lambdas, although they could, since you might change it in a future update.
Details
You can read about the precise definitions in JLS§9.8. Functional Interfaces:
A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.
And JLS§9.6.4.9. #FunctionalInterface:
The annotation type FunctionalInterface is used to indicate that an interface is meant to be a functional interface (§9.8). It facilitates early detection of inappropriate method declarations appearing in or inherited by an interface that is meant to be functional.
It is a compile-time error if an interface declaration is annotated with #FunctionalInterface but is not, in fact, a functional interface.
Because some interfaces are functional incidentally, it is not necessary or desirable that all declarations of functional interfaces be annotated with #FunctionalInterface.
The last paragraph here is especially important. I.e. you might have created a functional interface incidentally and plan to add more to it later. So people should not mistake this and use it with lambdas, otherwise their code will break later, when you add more methods.
Note
As mentioned before, the #Override tag works the same, but for overriding methods. So you can also override methods without it. But if you use it and maybe made a typo, i.e. you are not actually overriding something, the compiler will help you spot this issue immediately.
I am learning the Java 8 syntax and came across a piece of code in our application below in an interface:
default EmployeeEnricher employeeEnricher() {
return builder -> {
return;
};
}
Can someone please help me understand what the above syntax means?
There are multiple implementations of this method in the application, each with its own logic.
It just returns an EmployeeEnricher which basically is a Consumer<Builder> (or a functional interface from the same kind) which does nothing with its parameter meaning that if the class implementing the interface doesn't #Override this method, this will become its default behaviour (meaning nothing will happen).
In your application, you'll encounter different types of employees probably which will be enriched in different manners using a builder given in parameter using employeeEnricher().accept(builder)
This means implementation can mean two things for me :
Either the design is poor, and all employees should have their own implementation, meaning this interface's method should not have be default but simply a classic abstract method of the interface
Either some employees do not get enriched in the context of your application, and thus this method offers a default implementation making sense
Java 8 gave us many fun ways to use functional interfaces and with them a new annotation: #FunctionalInterface. Its job is to tell the compiler to yell at us if we fail to stick to the rules of a functional interface (only one abstract method that needs overriding please).
There are 43 interfaces in the java.util.function package with this annotation. A search of jdk.1.8.0/src for #FunctionalInterface only turns up 57 hits. Why are the other interfaces (such as AutoCloseable) that could have added #FunctionalInterface still missing it?
There is a bit of a vague hint in the annotations documentation:
"An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface"
Is there any good reason NOT to intend that an interface I've designed (that may simply happen to be a functional interface) not be used as one? Is leaving it off an indication of anything besides not realizing it could have been added?
Isn't adding abstract methods to any published interface going to screw anyone implementing it, functional or not? I feel cynical assuming they just didn't bother to hunt them all down but what other explanation is there?
Update: After looking over "Should 'Comparable' be a 'Functional interface'?" I find I still have nagging questions. When a Single Method Interface and a Functional Interface are structurally identical what's left to be different? Is the difference simply the names? Comparable and Comparator are close enough to the same semantically. Turns out they are different structurally though so still not the best example...
Is there a case when an SMI is structurally fine to use as a Functional Interface but still discouraged over the semantic meaning of the name of the interface and the method? Or perhaps the contract implied by the Javadocs?
Well, an annotation documenting an intention would be useless if you assume that there is always that intention given.
You named the example AutoCloseable which is obviously not intended to be implemented as a function as there’s Runnable which is much more convenient for a function with a ()->void signature. It’s intended that a class implementing AutoCloseable manages an external resource which anonymous classes implemented via lambda expression don’t do.
A clearer example is Comparable, an interface not only not intended to be implemented as a lambda expression, it’s impossible to implement it correctly using a lambda expression.
Possible reasons for not marking an interface with #FunctionalInterface by example:
The interface has programming language semantics, e.g. AutoClosable or Iterable (that’s unlikely to happen for your own interfaces)
It’s not expected that the interface has arbitrary implementations and/or is more an identifier than the actual implementation, e.g. java.net.ProtocolFamily, or java.lang.reflect.GenericArrayType (Note that the latter would also inherit a default implementation for getTypeName() being useless for lambda implementations as relying on toString())
The instances of this interface should have an identity, e.g. java.net.ProtocolFamily, java.nio.file.WatchEvent.Modifier, etc. Note that these are typically implemented by an enum
Another example is java.time.chrono.Era which happens to have only a single abstract method but its specification says “Instances of Era may be compared using the == operator.”
The interface is intended to alter the behavior of an operation for which an implementation of the interface without inheriting/implementing anything else makes no sense, e.g. java.rmi.server.Unreferenced
It’s an abstraction of common operations of classes which should have more than just these operations, e.g. java.io.Closeable, java.io.Flushable, java.lang.Readable
The expected inheritance is part of the contract and forbids lambda expression implementations, e.g. in java.awt: ActiveEvent should be implemented by an AWTEvent, PrinterGraphics by a Graphics, the same applies to java.awt.print.PrinterGraphics (hey, two interfaces for exactly the same thing…), wheras javax.print.FlavorException should be implemented by a javax.print.PrintException subclass
I don’t know whether the various event listener interfaces aren’t marked with #FunctionalInterface for symmetry with other multi-method event listener that can’t be functional interfaces, but actually event listeners are good candidates for lambda expressions. If you want remove a listener at a later time, you have to store the instance but that’s not different to, e.g. inner class listener implementations.
The library maintainer has a large codebase with more than 200 candidate types and not the resources to discuss for every interface whether it should be annotated and hence focuses on the primary candidates for being used in a functional context. I’m sure, that, e.g. java.io.ObjectInputValidation, java.lang.reflect.InvocationHandler, juc RejectedExecutionHandler & ThreadFactory wouldn’t be bad as #FunctionalInterface but I have no idea whether, e.g. java.security.spec.ECField makes a good candidate. The more general the library is, the more likely users of the library will be able to answer that question for a particular interface they are interested in but it would be unfair to insist on the library maintainer to answer it for all interfaces.
In this context it makes more sense to see the presence of a #FunctionalInterface as a message that an interface is definitely intended to be usable together with lambda expressions than to treat the absence of the annotation as an indicator for it’s being not intended to be used this way. This is exactly like the compiler handles it, you can implement every single abstract method interface using a lambda expression, but when the annotation is present it will ensure that you can use this interface in this way.
Planned expansion. Just because an interface matches the requirements of an SMI now doesn't mean that expansion isn't needed later.
In java 8, functional interface is an interface having exactly one abstract method called functional method to which the lambda expression’s parameter and return types are matched.
The java.util.function contains general purpose functional interfaces used by JDK and also available for end users. While they are not the complete set of funtional interfaces to which lambda expressions might be applicable, but they provide enough to cover common requirements. You are free to create your own functional interfaces whenever existing set are not enough.
There are many such interfaces available which deserves to be designated as functional interface but java.util.function package already provides functional interfaces for our almost all purposes.
For example look into following code.
public interface Comparable<T> {
public int compareTo(T o);
}
#FunctionalInterface
public interface ToIntFunction<T> {
int applyAsInt(T value);
}
public static void main(String[] args){
ToIntFunction<String> f = str -> Integer.parseInt(str);
Comparable<String> c = str -> Integer.parseInt(str);
}
Comparable can also take an object and derive some int type value but there is a more general dedicated interface ToIntFunction is provided to perform this task. There is no such hard rule that all the deserving interfaces should be annotated with #FunctionalInterface but to gain the advantage of lambda feature, the interface should fulfill all criterias defined by FunctionalInterface.
This question already has answers here:
Purpose of Default or Defender methods in Java 8
(5 answers)
Closed 8 years ago.
I'm taking a look to Java 8 news compared to 7 and in addition to very interesting things like lambdas or the new time framework, i found that a new feature(?) was introduced: default methods.
I found the following example in this article:
public interface Math {
int add(int a, int b);
default int multiply(int a, int b) {
return a * b;
}
}
It seems very strange to me.
Above code looks like an abstract class with an implemented method. So, why to introduce default methods in an interface? What is the actual advantage of this approach?
In the same article I read this explaination:
Why would one want to add methods into Interfaces? We’ll it is because interfaces are too tightly coupled with their implementation classes. i.e. it is not possible to add a method in interface without breaking the implementor class. Once you add a method in interface, all its implemented classes must declare method body of this new method.
Well this doesn't convince me at all. IMHO I believe that when a class implements an interface obviosly must declare methods body for each method in it. This is surely a constraint, but it's also a confirm of its "nature" (if you understand what I mean...)
If you have common logic to every inheriting class you'll put it into an implementing abstract class.
So, what's the real advantage of a default method? (It looks more like a workaround than a new feature...)
UPDATE I understand that this approach is for backwards compatibility, but it still doesn't convince me so much. An interface represent a behaviour that a class MUST have. So a class implementing a certain interface has surely this behaviour. But if someone can arbitrarily change the interface, this constraint is broken. The behaviour can change anytime... Am I wrong?
This is for backwards compatibility.
If you have an interface that other people have implemented then if you add a new method to the interface all existing implementations are broken.
By adding a new method with a default implementation you remaining source-compatible with existing implementations.
For a slightly simple/contrived example that should hopefully demonstrate this let us say you created a library:
void drawSomething(Thing thing) {
}
interface Thing {
Color getColor();
Image getBackgroundImage();
}
Now you come to do a new version of your library and you want to add the concept of border colors, that's easy to add to the interface:
interface Thing {
Color getColor();
Color getBorderColor();
Image getBackgroundImage();
}
But the problem is that every single person using your library has to go back through every single Skin implementation they ever did and add this new method.
If instead you provided a default implementation to getBorderColor that just called getColor then everything "just works".
There have been a lot of methods acting on an abstract interface in the past. Before Java 8 they had to be put into an additional class pairing the interface, e.g. Collections with Collection.
This old approach was neither more convincing than default methods nor more practical. Instead of list.sort() you had to say Collections.sort(list). This also implies that you had to make a fundamental decision when creating an interface, either you require every List implementation to implement a sort method or you provide a sort method in a utility class that cannot be overridden.
With default methods you can have both, a standard implementation which the List implementations do not need to implement on its own but still can be overridden if a concrete implementation has a more efficient way to do it knowing its internals, e.g. ArrayList.sort passes its internal array directly to Arrays.sort skipping some intermediate operations.
Suppose at some point you want to add new functionality in declared interface, up to Java 7, If you will add a new method in declared an interface, you also have to define the implementation of the method in classes that are implementing that interface.
In java 8, You can add a default method containing the implementation and all the child class will inherit that method.
Edit : (After question update)
An interface represent a behaviour that a class MUST have
It still represent a behaviour that class must have, your confusion is how you are defining behaviour. All implementing class will inherit default method and are also free to write their own implementation. consider following two cases,
If implementing class does not provide own implementation and simply inherit default method. If you change behaviour of default method in interface, implementing classes will be having updated behaviour as they inherit default method so it holds An interface represent a behaviour that a class MUST have.
If implementing class provide own version of default method, and if you will change behaviour (only arguments) of default method. In this case implementing class will be having two overloaded methods, one which was earlier defined and second one is inherited default method. and if you change complete behaviour (arguments with return type also), It will create ambiguity in implementing class as you can not overload method by changing return type and Implementation will be broken. again it holds An interface represent a behaviour that a class MUST have.
Example :
Bulk data operation in collection is added in Java 8 (Reference : http://openjdk.java.net/jeps/107), to implement that forEach() method is added in Iterable interface. Adding abstract method in Iterable interface would break all the existing code because each class has to implement that method.
Solving the issue, following default forEach() method is added in Iterable interface,
interface Iterable
{
default void forEach(Consumer<? super T> action)
{
for (T t : this) action.accept(t);
}
}
Reference : Java 8 : Default method in Interface
The definition of a functional interface is "A functional interface is an interface that has just one abstract method
(aside from the methods of Object ), and thus represents a single function contract."
According to this definition, the Comparable<T> is definitely a functional interface.
The definition of a lambda expression is "A lambda expression is like a method: it provides a list of formal parameters
and a body - an expression or block - expressed in terms of those parameters."
Evaluation of a lambda expression produces an instance of a functional interface.
Thus, the purpose of the lambda expression is to be able to create an instance of the functional interface, by implementing
the single function of the functional interface. ie. to allow the creation of an instance with the single function.
Let us look at Comparable<T>, is this interface designed for use as a single function?
ie. was it designed for the creation of instances with this single function only?
The documentation of Comparable<T> starts with "This interface imposes a total ordering on the objects of each class that
implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred
to as its natural comparison method."
The above sentence makes it clear that the Comparable<T> is not designed to be used as a single function, but is always
meant to be implemented by a class, which has natural ordering for its instances, by adding this single function.
Which would mean that it is not designed to be created by using a lambda expression?
The point is that we would not have any object which is just Comparable only, it is meant to be implemented and thus used
as an additional function for a class.
So, is there a way in the Java language, by which creation of a lambda expression for Comparable<T> is prevented?
Can the designer of an interface decide that this interface is meant to be implemented by a class and not meant to be
created as an instance with this single method by use of a lambda expression?
Simply because an interface happens to have a single abstract method, it should not be considered as a functional interface.
Maybe, if Java provides an annotation like NotFunctional, it can be checked by the compiler that this interface is not used
for the creation of a lambda expression, eg.
#NotFunctional
public interface Comparable<T> { public int compareTo(T t); }
A lambda expression can be used where an instance of an interface with a single abstract method is required. You wrote,
Simply because an interface happens to have single abstract method, it should not be considered as a functional interface.
This is exactly correct. Having a single abstract method is a structural property of an interface, one that makes it eligible to be implemented with a lambda. However, whether an interface makes sense or is semantically sensible to be implemented with lambda is a different story. The latter is the purpose of the #FunctionalInterface annotation. When it is present on an interface, it indicates the intent that the interface is useful to be implemented with a lambda.
Notably, the Comparable interface lacks the #FunctionalInterface annotation.
While it's probably nonsensical to use a lambda as a Comparable implementation, there doesn't seem to be any reason to create a mechanism to prevent this from being done. It doesn't seem like doing this would be a source of error, which would be a good reason to develop such a mechanism. By contrast, the #FunctionalInterface annotation is intended to guide programmers in the right direction instead of prohibiting something that is arguably wrong but doesn't seem truly harmful.
The issue comes from a subtle difference between a "method" and a "function".
The output value of a function depends ONLY on the arguments that are input to that function.
However the output of a method depends on the arguments that are input to the function but it may also depend on the object's state (instance variables).
That is, any function is a method but not all methods are functions.
For example, the method compare in the interface Comparator depends only on its arguments. However, the method compareTo in the interface Comparable depends on the state of the object to compare to, so it needs to be implemented in a class.
So even Comparable has one abstarct method, semantically it shouldn't be considered as a functional interface.
Well, asides from the discussion how usefull the informative annotation #FunctionalInterface is (and I am happy Java 8 does not require it for lambdas).
Comparable is typically a property of a type and therefore not a good candidate for a functional interface. It is explicitly described as the natural ordering and does not take the two this/that arguments. So this property makes it unlikely any method would operate on a lambda (similliar argument is applicable for nearly all -able interfaces).
So, the collection designers use a second interface for that task: Comparator<T>, and for that a lambda implementing it is a very natural choice.
There is no mechanism to prevent a naive use of an interface not intended to be a functional interface.
by having an additional annotation like #NotFunctional, it could be declared explicitly by a
designer of an interface, that it should not be used as lambda.
And by default if no annotation is specified, it can be considered as good as #Functional,
which is currently the case.