Lambda Expressions enable you to encapsulate a single unit of behavior and pass it to other code. You can use a lambda expressions if you want a certain action performed on each element of a collection, when a process is completed, or when a process encounters an error. Lambda expressions are supported by the following features:
Method References are compact, easy-to-read lambda expressions for methods that already have a name.
Default Methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. They are interface methods that have an implementation and the default
keyword at the beginning of the method signature. In addition, you can define static methods in interfaces.
New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in Java SE 8 describe new and enhanced classes that take advantage of lambda expressions and streams.
Improved Type Inference - The Java compiler takes advantage of target typing to infer the type parameters of a generic method invocation. The target type of an expression is the data type that the Java compiler expects depending on where the expression appears. For example, you can use an assignment statement's target type for type inference in Java SE 7. However, in Java SE 8, you can use the target type for type inference in more contexts. The most prominent example is using a method invocation's target types to infer the data types of its arguments.
Consider the following example:
List<String> stringList = new ArrayList<>(); stringList.add("A"); stringList.addAll(Arrays.asList());
Disregarding generics for the moment, the method addAll
expects a Collection
instance as its argument, and the method Arrays.asList
returns a List
instance. This works because List
is a subtype of Collection
.
Now considering generics, the target type of addAll
is Collection<? extends String>
, and Arrays.asList
returns a List<T>
instance. In this example, the Java SE 8 compiler can infer that the value of the type variable T
is String
. The compiler infers this from the target type Collection<? extends String>
.
Compilers from Java SE 7 and earlier do not accept this code because they do not use target typing to infer types for method call arguments. For example, the Java SE 7 compiler generates an error message similar to the following:
error: no suitable method found for addAll(List<Object>) ...
method List.addAll(Collection<? extends String>) is not applicable (actual argument List<Object> cannot be converted to Collection<? extends String> by method invocation conversion)
Consequently, in situations like this where the Java compiler cannot infer types, you must explicitly specify values for type variables with type witnesses. For example, the following works in Java SE 7:
List<String> stringList = new ArrayList<>(); stringList.add("A"); stringList.addAll(Arrays.<String>asList());
See the following sections in the Java Tutorials for more information:
Annotations on Java Types - It is now possible to apply an annotation anywhere a type is used. Used in conjunction with a pluggable type system, this allows for stronger type checking of your code. For more information, see Type Annotations and Pluggable Type Systems in the new Annotations lesson in the Java Tutorial.
Repeating Annotations - It is now possible to apply the same annotation type more than once to the same declaration or type use. For more information, see Repeating Annotations in the new Annotations lesson in the Java Tutorial.
Method Parameter Reflection - You can obtain the names of the formal parameters of any method or constructor with the method java.lang.reflect.Executable.getParameters
. (The classes Method
and Constructor
extend the class Executable
and therefore inherit the method Executable.getParameters
.) However, .class
files do not store formal parameter names by default. To store formal parameter names in a particular .class
file, and thus enable the Reflection API to retrieve formal parameter names, compile the source file with the -parameters
option of the javac
compiler. See Obtaining Names of Method Parameters in the Java Tutorials.
byte
, short
,
int
, and long
) can also be expressed
using the binary number system. To specify a binary literal, add
the prefix 0b
or 0B
to the number._
)
can appear anywhere between digits in a numerical literal. This
feature enables you, for example, to separate groups of digits in
numeric literals, which can improve the readability of your
code.String
class in the expression of a
switch
statement.<>
)
as long as the compiler can infer the type arguments from the
context. This pair of angle brackets is informally called the
diamond.-Xlint:varargs
and the annotations
@SafeVarargs
and @SuppressWarnings({"unchecked",
"varargs"})
to suppress these warnings.try
-with-resources
Statement - The try
-with-resources statement is a
try
statement that declares one or more resources. A
resource is an object that must be closed after the
program is finished with it. The try
-with-resources
statement ensures that each resource is closed at the end of the
statement. Any object that implements the new
java.lang.AutoCloseable
interface or the
java.io.Closeable
interface can be used as a resource.
The classes java.io.InputStream
,
OutputStream
, Reader
,
Writer
, java.sql.Connection
,
Statement
, and ResultSet
have been
retrofitted to implement the AutoCloseable
interface
and can all be used as resources in a
try
-with-resources statement.catch
block can handle more than one type of
exception. In addition, the compiler performs more precise analysis
of rethrown exceptions than earlier releases of Java SE. This
enables you to specify more specific exception types in the
throws
clause of a method declaration.for
Loop - This new language construct eliminates the drudgery
and error-proneness of iterators and index variables when iterating
over collections and arrays. (JSR 201)@Deprecated
annotation provides a way to
deprecate program elements. See How and When To Deprecate
APIs.