Context of trailing lambda - spring

Below you can see a trailing lambda syntax:
runApplication</*... */>(/*... */) {
setBannerMode(/*... */)
}
I understand the idea that we can pass a lambda outside the parens as a last argument. But what does the code above actually do? setBannerMode is a method that is going to override the one in the parent class, isn't it? If yes, what class is the parent one? Is there some this context between the braces of the trailing lambda? In general, what's happening there?
the code is from here

setBannerMode is a method that is being overriden, isn't it?
No. What you are doing is passing a lambda to runApplication() that has a this implicit receiver .
Here is the definition (Spring documentation):
inline fun <reified T : Any> runApplication(vararg args: String, init: SpringApplication.() -> Unit): ConfigurableApplicationContext =
SpringApplication(T::class.java).apply(init).run(*args)
The init: SpringApplication.() -> Unit here is the definition of the lambda with implicit receiver. It means that inside the lambda, this will be a SpringApplication.
To break it down:
SpringApplication(T::class.java) - create a new spring application. T is calculated from the calling context by the Kotlin compiler (that's what reified T means).
apply(init). Calls your lambda (init), with the SpringApplication as the receiver (Kotlin docs for apply).
Call the SpringApplication's run() function with the varargs arguments. This function returns a ConfigurableApplicationContext.
So, you are calling the setBannerMode() method of the instantiated SpringApplication object.

Related

Method Reference - passing Function to method with Consumer argument

I'm learning about Method References from Java 8 and I have difficulties understanding why does this work?
class Holder {
private String holded;
public Holder(String holded) {
this.holded = holded;
}
public String getHolded() {
return holded;
}
}
private void run() {
Function<Holder, String> getHolded = Holder::getHolded;
consume(Holder::getHolded); //This is correct...
consume(getHolded); //...but this is not
}
private void consume(Consumer<Holder> consumer) {
consumer.accept(null);
}
As you can see in run method - Holder::getHolded returns unbound method reference which you can invoke by passing object of type Holder as an argument. Like this: getHolded.apply(holder)
But why it casts this unbound method reference to Consumer when it is invoked directly as an method argument, and it does not doing it when I'm passing Function explicitly?
Two things here, lambda expressions are poly expressions - they are inferred by the compiler using their context (like generics for example).
When you declare consume(Holder::getHolded);, compiler (under the so-called special void compatibility rule) will infer it to Consumer<Holder>.
And this might not look obvious, but think of a simplified example. It is generally more than ok do call a method and discard it's return type, right? For example:
List<Integer> list = new ArrayList<>();
list.add(1);
Even if list.add(1) returns a boolean, we don't care about it.
Thus your example that works can be simplified to:
consume(x -> {
x.getHolded(); // ignore the result here
return;
});
So these are both possible and valid declarations:
Consumer<Holder> consumer = Holder::getHolded;
Function<Holder, String> function = Holder::getHolded;
But in this case we are explicitly telling what type is Holder::getHolded,, it's not the compiler inferring, thus consume(getHolded); fails, a Consumer != Function after all.
Java 8 introduced 4 important "function shapes" in the package java.util.function.
Consumer -> accepts a method reference (or a lambda expression) that takes one argument but doesn't return anything
Supplier -> accepts a method reference (or a lambda expression) that takes no argument and returns an object.
Function -> accepts a method reference (or a lambda expression) that takes one argument and returns an object.
Predicate -> accepts a method reference (or a lambda expression) that takes one argument and returns a boolean.
Read the Java docs for more detail.
To answer your question on why the first one works but the second one errors out, read following:
The second statement
consume(getHolded);
doesn't work because the type of the argument getHolded is Function<Holder, String> whereas the consume method expects an argument of type Consumer<Holder>. Since there is no parent-child relationship between Function and Consumer, it requires an explicit cast without which the compiler rightly errors out.
The first statement
consume(Holder::getHolded);
works because the method getHolded is declared as public String getHolded() meaning that it doesn't take any argument and returns a String. As per the new void compatibility rule, void types are inferred as the class containing the referenced method. Consider the following statement:
Consumer<Holder> consumer = Holder::getHolded;
This is a valid statement even though the method getHolded doesn't accept any arguments. This is allowed to facilitate inferring void types. Yet another example is the one you have mentioned yourself:
Function<Holder, String> getHolded = Holder::getHolded;
This is also a valid statement where you have said that the function object getHolded is a Function that returns String and accepts a type Holder even though the assigned method reference doesn't take any argument.
Sharing just a summary of the four types of Method References under the hood:
Reference to a static method:
Type::staticMethod ===>>> x -> Type.staticMethod(x)
Reference to an instance method of a particular object:
instance::instanceMethod ===>>> x -> instance.instanceMethod(x)
Reference to an Instance Method of an Arbitrary Object of a Particular Type:
Type::instanceMethod ===>>> x -> x.instanceMethod() OR (x, y) -> x.instanceMethod(y)
Reference to a constructor:
Type::new ===> x -> new Type(x)

Java 8 - Static Method Reference Rule

I have the following piece of code:
public class Chap20 {
public static void main(String[] args) {
String[] names = { "John", "Jane" };
Stream<String> namesStream = Stream.of(names);
Path path = Paths.get(".");
Stream<Path> files;
try {
files = Files.list(path);
files.forEach(System.out::println);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now here´s the file.forEach method signature:
void java.util.stream.Stream.forEach(Consumer<? super Path> action)
I´m reading it as a method that accepts a consumer of a type which is at least a Path type or a superclass of Path, but I´m probably missreading it, since System.out is not a superclass of Path.
Can someone please explain how to correct read it?
? super Path says: 'It has to be a super class of Path.
System.out.println accepts an Object. Object is a super class of Path hence this is correct.
You are reading that entirely correct IMO, you are just mislead by the :: notation probably. And it's not about System.out being a Path or not - it's about the implied parameter x (for example) that you can't see because of the method reference (read further).
There are a couple of things here, first one is called PECS; that is why the declaration is ? super P_OUT or ? super Path. Basically that means you can read any super type of Path. The only safe one would be Object (or any sub type of that, but you just don't know which exactly).
To make it simpler, you can write it like this for example:
Stream.of("John", "Jane")
.forEach((Object x) -> System.out.println(x)); // Object
Or since the compiler can see (infer) the type to be String :
Stream.of("John", "Jane")
.forEach((String x) -> System.out.println(x)); // String
Or you can omit that declaration at all and let the compiler do it's job:
Stream.of("John", "Jane")
.forEach(/* this is infered as String here */ x -> System.out.println(x));
Now the second part is called a Method Reference.
Instead of writing:
Stream.of("John", "Jane")
.forEach(x -> System.out.println(x));
You could write it simpler:
Stream.of("John", "Jane")
.forEach(System.out::println);
The x parameter (which is of type ? super T) is implied here.
The method signature indicates the forEach method of Stream takes a Consumer, which consumes each element from the Stream upon which it is iterating, in your case a collection of Paths.
Consumer refers to a functional interface that accepts an input and returns no result. It is one of many implemented in Java 8 to work with Lambdas and method references. A functional interface contains exactly one abstract method, also called its functional method.
The forEach method is used for iterating over a collection and applying an operation on each element. The operation, or "behavior" (any class implementing the Consumer interface), that's passed is the action, or lambda, performed on each element of the collection.
The forEach is an API (also added with Java 8) in the Iterable interface, which "performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception". It differs from the Java for loop in that it is an internal iterator, rather than an external one.

Why use spyOn instead of jasmine.createSpy?

What is the difference between
jasmine.createSpy('someMethod')
And
spyOn(someObject, 'someMethod')
And why should one choose to use spyOn?
My guess is that the first alternative will match the method someMethod no matter in what object it's contained but spyOn will only match if it's contained in someObject. Thus making createSpy just a more generic matcher?
The difference is that you should have a method on the object with spyOn
const o = { some(): { console.log('spied') } };
spyOn(o, 'some');
while the mock method is created for your with createSpy():
const o = {};
o.some = jasmine.createSpy('some');
The advantage of the spyOn is that you can call the original method:
spyOn(o, 'some').and.callThrough();
o.some(); // logs 'spied'
And as #estus says the original method is restored after the test in case of spyOn. This should be done manually when it's reassigned with.
Additionally to the other fine answer:
Use spyOn() to spy (intercept) an existing method on an object to track calls of other modules to it.
Use jasmine.createSpy() to create a function that can be passed as callback or Promise handler to track call-backs.

Reference to an instance method of a particular object breaks the type-safety in Java?

Does the notion of a reference to an instance method of a particular object break the type-safety in Java?
According to
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
you can have a custom class ComparisonProvider that DOES not implement the Comparator interface, and still use an instance of this class as the second argument of the method
Arrays.sort(T[] a, Comparator c)
Sure, the implementation of your ComparisonProvider MUST have a method whose signature exactly matches the Comparator.compare() method, but that is still not an instance of Comparator, isn't it?
In essence, Java 8 allows us to use instances of classes as if they were implementing a particular interface, while actually they are not.
This means, that we are loosing Type-safety in Java, do we?
lambda expressions and method reference don't have a predefined type, they are poly expressions, as seen here. That means that their type is derived from the context in which they are used.
In your example these both would be legal for example:
BiFunction<Person, Person, Integer> biFun = myComparisonProvider::compareByName;
Comparator<Person> comp = myComparisonProvider::compareByName;
But at the same time you can't do:
Arrays.sort(pers, biFun);
When you actually try to sort the array like this:
Arrays.sort(pers, myComparisonProvider::compareByName);
At the bytecode level that is a Comparator:
// InvokeDynamic #0:compare:(LTest$ComparisonProvider;)Ljava/util/Comparator;
Also notice that this would print true:
Comparator<Person> comp = myComparisonProvider::compareByName;
System.out.println(comp instanceof Comparator); // true
You can enable a flag : -Djdk.internal.lambda.dumpProxyClasses=/Your/Path/Here
and look at what that method reference is transformed into:
final class Test$$Lambda$1 implements java.util.Comparator
and inside it there's the compare method implementation(I've simplified it and removed some of it's code to make it a little more obvious):
public int compare(java.lang.Object, java.lang.Object);
Code:
4: aload_1
5: checkcast // class Test3$Person
8: aload_2
9: checkcast // class Test$Person
12: invokevirtual Test$ComparisonProvider.compareByName:(Test$Person;Test$Person;)I
Java 8 allows us to use instances of classes as if they were implementing a particular interface, while actually they are not
Not exactly, it allows you to use a single method of some instance of a class as if it were implementing some functional interface.
And it doesn't add any functionality that didn't exist in Java 7 - it just gives you a short cut to writing that functionality.
For example, instead of:
Arrays.sort(someArray, someInstance::someMethod);
In Java 7 you could use anonymous class instance to write:
Arrays.sort(someArray, new Comparator<SomeType> () {
public int compare (SomeType one, SomeTypeTwo) {
return someInstance.someMethod(one,two);
}
});
As long as the instance method is accessible (i.e. public), you can use it as you see fit.
Comparator is a functional interface, which means that when requested you can pass an instance of a class implementing it, use a lambda expression that conforms to the type of single abstract method declared in it or use a method reference that also conforms to.
Java 8 Functional interface makes the difference. This tries to catch the concept of function. Afterall what is important in Comparator is not the type itself but the method (and its type) that should be provided at runtime. In pre Java 8 you need to provide a function object, while in Java 8 you can simply provide the function (just what is needed).
So for the type system everything is correct, provided that the lambdas or references you use are of the type of the method of the functional interface.

Are c++11 lambda targets statically created?

I have a following method:
using async_handler_t = std::function<void(boost::system::error_code, std::size_t)>;
async_handler_t deadlineHandler(boost::system::error_code &ec) {
return [&ec, this](boost::system::error_code newEc, std::size_t) {
ec = newEc;
deadline_.cancel();
};
}
This is simple asio deadline handler which stops the deadline timer and allows the io_service-run loop to continue (grabbed this from official asio timeout docs).
The question is about how much times the function itself is generated. I understand, that I return a functional object from this method (std::function object) which is created dynamically during runtime but is the target function created only once?
The code inside the body of the lambda will only be compiled once and all instances of that lambda's closure object type will share the code. But each call to deadlineHandler will result in a new instance of the closure type being created, its members ec and this being initialised, and then a std::function object being created from that instance.
The lambda expression implicitly declares a functor class, and creates an instance of it.
The generation of the class' type (and the code of its operator()) is, of course, done once at compile-time.
A new instance of this class (containing what the lambda captured) is created each time you call your function.

Resources