1. Interface improvement
A. Static methods can be defined in an interface
B. More importantly, the method in the interface can be modified with the default, adding a method body
2. Why can't I use the default method to override the Equals,hashcode,tostring method?
That is, the interface cannot provide a default implementation of any method on the object class. If a class implements a method, it always takes precedence over the default implementation. Once all instances of the interface are subclasses of object, all interface instances already have a non-default implementation of Equals/hashcode/tostring. Therefore, a default version of these on the interface is useless, and it will not be compiled.
3. Function-Type interface
The core concept is the functional interface. If an interface defines a unique abstract method, then this interface becomes a functional interface. For example, Java.lang.Runnable is a functional interface because it only defines an abstract method:
public abstract void run ();
What is a functional interface, there are two cases: 1. The interface has only one abstract method, the abstract modifier 2. The interface has only one abstract method, which is an abstraction. At the same time, there are several default methods, because the default is to be decorated by the defaults, not by the abstract.
At the same time, a new annotation is introduced: @FunctionalInterface. Can put him in front of an interface, indicating that this interface is a functional interface. Plus its interface will not be compiled unless you try to turn it into a functional interface. It's kind of like @override, which declares a use intent to avoid you using it wrong.
4.Lambdas
A very valuable property of a functional interface is that they are able to instantiate with Lambdas. Here are some examples of lambdas:
On the left is a comma-separated list of inputs of the specified type, and the right is a code block with a return:
(return x + y;}
On the left is a comma-separated input list of derivation types, and the right is the return value:
x + y (x, y)
On the left is a single argument of the derivation type, and the right is a return value:
X-X * x
No input on the left (official name: "Burger Arrow"), return a value on the right:
() x
The left side is a single argument of the derivation type, and to the right is a block of code with no return value (return void):
X, {System.out.println (x);}
static method References:
String::valueof
Non-static method references:
Object::tostring
inherited function References:
X::tostring
Constructor Reference:
ArrayList::
You can think of some function reference formats as shorthand for other lambda formats.
Method Reference |
an equivalent lambda expression |
|
String::valueof |
|
X-string.valueof (x) |
Object::tostring |
|
X-x.tostring () |
X::tostring |
|
() x.tostring () |
Arraylist::new |
|
()-New arraylist<> () |
Of course, the method can be overloaded in Java. A class can have multiple methods with the same name but different parameters. This is also valid for the construction method. Arraylist::new can point to either of its 3 constructor methods. Decide which method to use is based on the function interface in use.
A lambda and a given functional interface are compatible when the "outer" match is in the form. With "outer form", I point to the input, the type of output, and the declaration check exception.
Give two examples that are specific and valid:
Comparator<string> C = (A, b), Integer.compare (A.length (), b.length ());
A comparator<string> compare method needs to enter two elaboration, and then returns an int. This is consistent with the right side of the lambda, so this task is valid.
Runnable r = () {System.out.println ("running!");}
A runnable run method does not require parameters and does not return a value. This is consistent with the right side of the lambda, so the task is valid.
It is also important to check for exceptions (if any) in the signature of an abstract method. If the function-type interface declares an exception in its signature, lambda can only throw a check exception.
5. Capture and non-capturing of Lanbdas expressions
When a lambda expression accesses a non-static variable or object defined outside the body of a lambda expression, the lambda expression is called "captured." For example, the following lambda expression captures the variable x:
return y x + y;
To ensure that the lambda expression declaration is correct, the variable it captures must be "valid final". So either they need to be marked with final modifier symbols, or they are guaranteed to not change after assignment.
Whether a lambda expression is captured and is quietly related to performance. A non-trapping lambda is usually more efficient than capturing, although there is no written specification (as far as I know), and there is no reason to expect it to do anything for the correctness of the program, and a non-capturing lambda needs to be computed only once. Then each time it is used, it returns a unique instance. The captured lambda expression needs to be recalculated each time it is used, and from the current implementation it is much like instantiating an instance of an anonymous inner class.
6. Other
Lambdas don't do.
You should remember that there are some features that lambdas do not provide. For Java 8 They are considered, but are not included, due to the reasons of simplification and time limitation.
non-final* variable capture -If a variable is given a new value, it will not be used in lambda. The "final" keyword is not required, but the variable must be "valid final" (discussed earlier). This code will not be compiled:
int 0; List<string> strings = Arrays.aslist ("a""b" "C") Strings.foreach (s) { Error:can ' t modify the value of Count});
exception Transparency -If a detected exception can be thrown from within a lambda, the functional interface must also declare that the detected exception can be thrown. This exception is not distributed to the methods it contains. This code will not be compiled:
void Appendall (iterable<string> values, appendable out) throws //doesn ' t help with the error Values.foreach (s, { //Error:can ' t throw IOException here//consume R.accept (t) doesn ' t allow it});
There is a way around this, you can define your own functional interface, extend the consumer at the same time by throwing ioexception like runtimeexception. I tried to write it out in code, but it was worth it to find it confusing.
control Flow (break, early return) -in the above foreach example, the traditional continuation method is possible by placing "return" within the lambda; To achieve. However, there is no way to break the loop or return a value from the lambda with the result of the containing method. For example:
Final "foo" booleancontainssecret(iterable<string> values) { if (Secret.equals (s)) { //Want to end of the loop and return true, but can ' t} });}
Read more about these questions and see what this Brian Goetz wrote: Responding to "verified exceptions" in block<t>super0555
Other translation versions (1)Why abstract classes cannot be instantiated by using lambda
Abstract classes, even if only an abstract method is declared, and cannot be instantiated using lambda.
Here are two examples of classes ordering and Cacheloader, all with an abstract method, excerpted from the Guava library. Wouldn't it be nice to be able to declare their instances, using lambda expressions like this?
Ordering<string> order = (A, b) ...;
cacheloader<string, string> loader = (key) ...;
The most common argument for this is that it can increase the difficulty of reading Lambda. Instantiating an abstract class in this manner will result in the execution of the hidden code: The method of constructing the abstract class.
Another reason is that it throws a possible optimization of the lambda expression. In the future, it may be the case that lambda expressions are not evaluated to an object instance. Allowing users to declare abstract classes with lambda will hinder optimizations like this.
Outside of This , there is a simple workaround. In fact, the above two instance classes from the guava library have demonstrated this approach. Adding a factory method converts lambda into an instance.
Ordering<string> order = Ordering.from ((A, B), ...); cacheloader<string, string> loader = Cacheloader.from ((key), ...);
to read more, take a look at the instructions from Brian Goetz: Response to "let lambdas to implement abstract classes".
Java.util.function
Package Overview: Java.util.function
As the early proof of comparator and runnable, interfaces already defined in the JDK happen to be compatible with Lambdas expressions as function interfaces. The same way you can define any function interface or third-party library in your own code.
But there is a specific form of the function interface, and extensive, universal, in the previous JD card does not exist. A large number of interfaces are added to the new java.util.function package. Here are some of them:
- Function<t, r>-T as input, return R as output
- Predicate<t>-T as input, returns a Boolean value as output
- Consumer<t>-T as input, performs some action but no return value
- supplier<t>-No input, return T
- Binaryoperator<t>-Two t as input, returns a T as output and is useful for the "reduce" operation
These most primitive characteristics are likewise present. They are provided in Int,long and double form. For example:
- Intconsumer-takes int as input, performs some action, no return value
There are some performance reasons, mainly in the input or output to avoid boxing and unpacking operations.
You should remember that there are some features that lambdas do not provide. For Java 8 They are considered, but are not included, due to the reasons of simplification and time limitation.
non-final* variable capture -If a variable is given a new value, it will not be used in lambda. The "final" keyword is not required, but the variable must be "valid final" (discussed earlier). This code will not be compiled:
int 0; List<string> strings = Arrays.aslist ("a""b" "C") Strings.foreach (s) { Error:can ' t modify the value of Count});
exception Transparency -If a detected exception can be thrown from within a lambda, the functional interface must also declare that the detected exception can be thrown. This exception is not distributed to the methods it contains. This code will not be compiled:
void Appendall (iterable<string> values, appendable out) throws //doesn ' t help with the error Values.foreach (s, { //Error:can ' t throw IOException here//consume R.accept (t) doesn ' t allow it});
There is a way around this, you can define your own functional interface, extend the consumer at the same time by throwing ioexception like runtimeexception. I tried to write it out in code, but it was worth it to find it confusing.
control Flow (break, early return) -in the above foreach example, the traditional continuation method is possible by placing "return" within the lambda; To achieve. However, there is no way to break the loop or return a value from the lambda with the result of the containing method. For example:
Final "foo" booleancontainssecret(iterable<string> values) { if (Secret.equals (s)) { //Want to end of the loop and return true, but can ' t} });}
Read more about these questions and see how this Brian Goetz wrote: Responding to "verified exceptions" in block<t>
super0555 translated more than 4 years ago4Man TopTopWell translated! Other translation versions (1)Why abstract classes cannot be instantiated by using lambda
Abstract classes, even if only an abstract method is declared, and cannot be instantiated using lambda.
Here are two examples of classes ordering and Cacheloader, all with an abstract method, excerpted from the Guava library. Wouldn't it be nice to be able to declare their instances, using lambda expressions like this?
Ordering<string> order = (A, b) ...;
cacheloader<string, string> loader = (key) ...;
The most common argument for this is that it can increase the difficulty of reading Lambda. Instantiating an abstract class in this manner will result in the execution of the hidden code: The method of constructing the abstract class.
Another reason is that it throws a possible optimization of the lambda expression. In the future, it may be the case that lambda expressions are not evaluated to an object instance. Allowing users to declare abstract classes with lambda will hinder optimizations like this.
Outside of This , there is a simple workaround. In fact, the above two instance classes from the guava library have demonstrated this approach. Adding a factory method converts lambda into an instance.
Ordering<string> order = Ordering.from ((A, B), ...); cacheloader<string, string> loader = Cacheloader.from ((key), ...);
to read more, take a look at the instructions from Brian Goetz: Response to "let lambdas to implement abstract classes".
And so on PM translated more than 4 years ago2Man TopTopWell translated! Java.util.function
Package Overview: Java.util.function
As the early proof of comparator and runnable, interfaces already defined in the JDK happen to be compatible with Lambdas expressions as function interfaces. The same way you can define any function interface or third-party library in your own code.
But there is a specific form of the function interface, and extensive, universal, in the previous JD card does not exist. A large number of interfaces are added to the new java.util.function package. Here are some of them:
- Function<t, r>-T as input, return R as output
- Predicate<t>-T as input, returns a Boolean value as output
- Consumer<t>-T as input, performs some action but no return value
- supplier<t>-No input, return T
- Binaryoperator<t>-Two t as input, returns a T as output and is useful for the "reduce" operation
These most primitive characteristics are likewise present. They are provided in Int,long and double form. For example:
- Intconsumer-takes int as input, performs some action, no return value
There are some performance reasons, mainly in the input or output to avoid boxing and unpacking operations.
And so on PM translated more than 4 years ago2Man TopTopWell translated!
All translations in this article are for learning and communication purposes only, please be sure to indicate the translator, source, and this article link our translation work in accordance with the CC agreement, if our work has violated your rights and interests, please contact us in time to review ( -)
Java8 new Features