New Features of Java 8-New Features of languages
1. Lambda expressions and functional interfaces
It allows us to pass functions as parameters to a method, or treat code as data processing: function developers are very familiar with these concepts. Many languages on the JVM platform (Groovy, Scala, and so on) Support Lambda expressions since their birth. However, Java developers have no choice but to replace Lambda expressions with anonymous internal classes.
The simplest Lambda expression can consist of a comma-separated parameter list, a-> symbol, and a statement block.
1. expression syntax:
Lambda expressions are used to represent a function. Therefore, like a function, Lambda expressions have parameters, return values, and function bodies, but they do not have function names. Therefore, Lambda expressions are equivalent to an anonymous function. Syntax:
NOTE 1: The parameter types in the above Code are explicitly specified. Of course, they can also be inferred by the compiler. For example:
Arrays. asList ("a", "B", "d"). forEach (e-> System. out. println (e ));
NOTE 2: If a Lambda expression requires more complex statement blocks, you can use curly brackets to enclose these block statements, similar to the function bodies in Java. For example:
Arrays. asList ("a", "B", "d"). forEach (e-> {
System. out. print (e );
System. out. print (e );
});
NOTE 3: Lambda expressions can reference class members and local variables (these variables are implicitly converted to final). For example, the effects of the following two code blocks are identical:
String separator = ",";
Arrays. asList ("a", "B", "d"). forEach (
(String e)-> System. out. print (e + separator ));
And
Final String separator = ",";
Arrays. asList ("a", "B", "d"). forEach (
(String e)-> System. out. print (e + separator ));
1.2.use lambda expressions
Take the Person object whose age is greater than 10 as an example:
1.2.1. Define functional interfaces for Lambda expressions
@ FunctionalInterface
Interface FilterProcessor <T> {
Boolean process (T t );
}
Lambda designers have considered many methods to make existing functions compatible with Lambda expressions, so they have developed the concept of function interfaces. A function interface refers to an interface with only one function. Such an interface can be implicitly converted to a Lambda expression. Java. lang. Runnable and java. util. concurrent. Callable are the best examples of functional interfaces. In practice, a functional interface is very fragile: As long as a developer adds a function to this interface, this interface is no longer a functional interface, resulting in compilation failure. To overcome this code vulnerability and explicitly show that an interface is a functional interface, java 8 provides a special annotation @ FunctionalInterface (all related interfaces in the Java library already carry this annotation). For example, the definition of a simple function interface:
When defining a functional interface for a Lambda expression, add the annotation @ FunctionalInterface. This interface can only have one abstract function. If the number of Abstract Functions in this interface is not 1, an error is returned.
However, you must note that the default and static methods (as described below) do not destroy the definition of functional interfaces.
1.2.2. filter functions
List <T> filter (List <T> list, FilterProcessor <T> filterProcessor ){
List <T> result = new ArrayList <T> ();
If (filterProcessor. process (t ))
Result. add (t );
Return result;
}
The filter function receives a function interface, which is used to receive a Lambda expression.
1.2.3. Pass the Lambda expression
List <Person> result = filter (list, (Person p)-> p. getAge ()> 10 );
Directly pass the Lambda expression as a parameter to the filter function interface, so that the Person object older than 10 can be obtained in the result.
Ii. Default and static Interfaces
Java 8 uses two new concepts to extend the meaning of interfaces: Default methods and static methods.
1. the default method makes the interface a bit similar to traits, but the goals to be achieved are different. The default method allows developers to add new methods to existing interfaces without compromising the binary compatibility, that is, they do not force the classes that implement this interface to implement this new method at the same time.
The difference between the default method and the abstract method is that the abstract method needs to be implemented, but the default method does not. The default method provided by the interface is inherited or overwritten by the Implementation class of the interface.
2. Another interesting feature of Java 8 is that static methods can be defined in Interfaces. The example code is as follows:
Private interface DefaulableFactory {
// Interfaces now allow static methods
Static Defaulable create (Supplier <Defaulable> supplier ){
Return supplier. get ();
}
}
The implementation of default methods on JVM provides support at the bytecode level, so the efficiency is very high. The default method allows you to improve interfaces without breaking the existing inheritance system. This feature is used in the official library to add new methods to the java. util. Collection interface, such as stream (), parallelStream (), forEach (), and removeIf.
Although the default method has so many advantages, it should be used with caution in actual development: in complex inheritance systems, the default method may cause ambiguity and compilation errors.
Iii. Method reference
Method reference allows developers to directly reference existing methods, Java class constructor methods, or instance objects. Method reference and Lambda expressions are used together to make java class constructor looks compact and concise, without a lot of complicated template code.
In the following example, the Car class is an example of different method references, which helps readers distinguish between four types of method references.
Public static class Car {
Public static Car create (final Supplier <Car> supplier ){
Return supplier. get ();
}
Public static void collide (final Car ){
System. out. println ("Collided" + car. toString ());
}
Public void follow (final Car another ){
System. out. println ("Following the" + another. toString ());
}
Public void repair (){
System. out. println ("recyclred" + this. toString ());
}
}
The type referenced by the first method is the constructor reference. The syntax is Class: new, or a more general form: Class <T >:: new. Note: This constructor has no parameters.
Final Car car = Car. create (Car: new );
Final List <Car> cars = Arrays. asList (car );
The second method reference type is static method reference. The syntax is Class: static_method. Note: This method accepts a parameter of the Car type.
Cars. forEach (Car: collide );
The third type of method reference is the reference of a member method of a Class. The syntax is Class: method. Note that this method does not define an input parameter:
Cars. forEach (Car: repair );
The fourth method reference type is the reference of the member methods of an instance object. The syntax is instance: method. Note: This method accepts a Car type parameter:
Final Car police = Car. create (Car: new );
Cars. forEach (police: follow );
Iv. Repeated annotations
Since Java 5 introduced annotations, this feature has become very popular and widely used in various frameworks and projects. However, there is a large limit on Annotations: The same annotation cannot be used multiple times in the same place. Java 8 breaks this restriction and introduces the concept of repeated annotations, allowing the same annotation to be used multiple times in the same place.
In Java 8, the @ Repeatable annotation is used to define repeated annotations. In fact, this is not a language improvement, but a trick made by the compiler. The underlying technology is still the same.
5. Better type inference
The Java 8 compiler greatly improves the type inference. In many scenarios, the compiler can deduce the Data Type of a parameter, making the code more concise.
6. Broaden the application scenarios of annotations
Java 8 expands the application scenarios of annotations. Currently, annotations can be used almost on any element: local variables, interface types, superclasses, and interface implementation classes, or even on function exception definitions.
This article permanently updates link: https://www.bkjia.com/Linux/2018-02/151054.htm