Which are the rules that make an Interface capable of being used as trailing lambda argument?
I though that the only rule was for it to be having a unique function on its definition, however I got myself into the following problem:
I had this Java interface
public interface ToolbarFragmentCallBack {
void onNavigationClick();
}
Called from a java class:
public void addToolBar(int container, String title, boolean isParent,
ToolbarFragment.ToolbarFragmentCallBack callback) {
//do something
}
Which was called from both Kotlin and Java files:
Kotlin (1):
addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
presenter.onClickNavigationToolBar()
}
Java (2):
addToolBar(R.id.toolbar_fragment, definition.getTitle(), false, () -> {
activity.onBackPressed();
});
However, I recently migrated the interface to Kotlin:
interface ToolbarFragmentCallBack {
fun onNavigationClick()
}
And now the **Kotlin (1) ** implementation calls don't compile, with message
Type mismatch: inferred type is () -> Unit but
ToolbarFragment.ToolbarFragmentCallBack! was expected
Edit:
It is now possible with Kotlin 1.4.
Note, however, that SAM conversions still won't work with standard interfaces, you have to explicitly declare your interface as a functional interface:
fun interface ToolbarFragmentCallBack {
fun onNavigationClick()
}
addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
presenter.onClickNavigationToolBar()
}
Old Answer:
For now Kotlin supports SAM conversions for Java interfaces only
(see docs):
Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.
However, that is about to change with the new version 1.4 (see What to Expect in Kotlin 1.4):
The community has requested us to introduce support for SAM conversions for Kotlin classes. [...] SAM conversions currently only work for Java interfaces and abstract classes. The initial idea behind this design was to use function types explicitly for such use-cases. It turned out, however, that function types and typealiases don’t cover all the use-cases, and people often had to keep an interface in Java only to get a SAM-conversion for it.
Related
I'm using Kotlin 1.6.10, Mockito 4.0.0 and Java 8 and I have a Java interface defined like this:
public interface MyInterface {
<D, T extends MyObject<T, D>> T doThings(T myObject);
}
An implementation of this interface is used in a Kotlin application and we have a unit test in which we want to make sure that the doThings method is never called using Mockito. In Java I would just do like this:
verify(myInterfaceInstance, never()).doThings(any());
But if I do this in Kotlin I get a compile-time error:
verify(myInterfaceInstance, never()).doThings(any())
Not enough information to infer type variable D
I understand why this is the case, but I cannot get it to work. In this particular case I really don't care about the generic types, I just want to make sure the doThings is never called. I've tried a lot of different things, for example:
verify(myInterfaceInstance, never()).doThings<Any, MyObject<*, Any>>(any())
which fails with:
Type argument is not within its bounds.
Expected:
MyObject<MyObject<*, Any>!, TypeVariable(D)!>!
Found:
MyObject<*, Any!>!
and I've also tried:
verify(myInterfaceInstance, never()).doThings<Any, MyObject<*, *>>(any())
and several other permutations which all seem to fail with roughly the same error message.
So my question is, how can I do the equivalent of Java's verify(myInterfaceInstance, never()).doThings(any()); in Kotlin?
This compiles fine, but issues a couple of warnings, you could suppress them via respectful annotation:
#Suppress("TYPE_MISMATCH_WARNING", "UPPER_BOUND_VIOLATED_WARNING")
verify(myInterfaceInstance, never()).doThings<Any, MyObject<*, *>?>(any<MyObject<*, *>>())
This is not a Mockito answer, but would the Library Mockk help you? MockK is built specifically for Kotlin so it might have better supports for Generics handling.
The verification would look like:
verify(exactly = 0) { yourClass.doThings(any()) };
https://notwoods.github.io/mockk-guidebook/docs/mocking/verify/
https://mockk.io/#verification-atleast-atmost-or-exactly-times
In developing a Groovy library to be used with Java code, I want to be able to use Java Lambdas than Groovy specific mechanisms.
When accessing this library API from the Java side the user should not need any Groovy specific imports or expose any Groovy specifics features.
Java-specific Lambdas could be pass to the API and also Java-specific Lambdas should be returned from the API.
Is there a way that this can be achieved?
E.g.
def f() {
return { n -> n + 1}
}
The return type of f is groovy.lang.Closure. I want it to be Function.
Also, instead of
def f(Closure c) {
...
c.delegate = this
c.resolveStrategy = DELEGATE_ONLY
...
}
I want to replace Closure c with Function.
In doing so when using it from the Java side Groovy features and API are not exposed to the developer.
The short answer is that you will be able to do this just like in Java.
In java a lamda is accepted as an object that implements a functional interface - a functional interface being an interface that contains only a single abstract method which matches the signature of the lambda you will pass in.
As an example, you can use the Runnable interface which has just a run method with no parameters.
In groovy you will accept an object of type Runnable:
def myGroovyFunction(Runnable r) {
r.run()
}
You can use any functional interface here, for example something from java.util.function or your own interface.
your java code can now pass in a lambda like so:
MyGroovyClass.myGroovyFunction(() -> {
System.out.println("This will be printed by the groovy function");
})
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));
The question came up when I took a closer look at kotlin .map inline function. Here's its definition
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R>{
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)}
In the function definition, it should return a List, which is defined in Collection.kt. However, it is returning an ArrayList, which implements a List interface in Java (List.java)
What is the relationship between Java interface and Kotlin interface ? I imagine there would be more similar examples, maybe Set, or Map?
On the JVM platform, the Kotlin interface kotlin.collections.List is mapped to Java interface java.util.List, and so is kotlin.collections.MutableList.
It means that the usages of these Kotlin interfaces are compiled to usages of the Java List interface in the bytecode. On the other hand, the Java List interface usages in the signatures read from the libraries are seen as kotlin.collections.(Mutable)List.
There are more mapped types: see the reference.
This allows for calling Kotlin from Java and vice versa in a seamless way while still representing the Java types as kotlin.* classes in Kotlin, which, for example, saves us from primitives and arrays not being classes, and introduces immutability through interfaces.
Is there something like Java's annotations in C++ ?
For example, the #Override annotation marks a function that it overrides another function, and if it wouldn't, it would give an error at compile time.
I am looking for something like this in C++.
C++11 provides support for generalized attributes, which can be seen as superset of Java annotations, as they can be applied not just to variables/functions, but also to statements, for example. But C++11 defines only syntax for generalized attributes, not means for user to define them.
This article gives good overview of generalized attributes: http://www.codesynthesis.com/~boris/blog/2012/04/18/cxx11-generalized-attributes/
GCC supports this feature from version 4.8, according to: http://gcc.gnu.org/projects/cxx0x.html
To implement support for user-defined attributes, compiler plugins are promising, especially based on high-level language integration, like https://fedorahosted.org/gcc-python-plugin/
C++0x will have this feature, where you can explicitly specify whether a member function is meant to override a base class' function, use a default implementation generated by the compiler and much more.
There is C++0x, which has the override 'annotation'. Or, if you wanted to achieve more of the Java "interface" like-code that errors if you don't implement methods, you could use an abstract class:
class Base {
public:
virtual void foo() = 0;
};
class Extended : public Base {
public:
void foo2() {
cout << "hi" << endl;
};
int main() {
Extended e;
e.foo();
}
This will result in a compiler error if you don't override foo in the base class. The issue, however, is that the base class can't have it's own implementation.
There's nothing in the language for this. The best you could hope for is a compiler-specific option. I'd start by checking the documentation for "pragma" for your compiler.
I'm not sure what JAVA provides in general, but for the specific functionality you mentioned, C++ has the override keyword:
class Derived : public Base {
void foo() override { ... }
};
You'll get a helpful compiler error message if Base doesn't have a corresponding virtual void foo().
Another functionally-similar keyword is final, which can be used to say that the function is an override that can't be further overridden in further-derived classes. (The same keyword can be used to say a class can't be derived from).