Java Reference
In-Depth Information
Logger logger = new
new Logger ();
iif ( logger . isDebugEnabled ()) {
logger . debug ( "Look at this: " + expensiveOperation ());
}
What we actually want to be able to do is pass in a lambda expression that generates a
String to be used as the message. This expression would be called only if the Logger was
actually at debug level or above. This approach would allow us to rewrite the previous code
example to look like the code in Example 4-2 .
Example 4-2. Using lambda expressions to simplify logging code
Logger logger = new
new Logger ();
logger . debug (() -> "Look at this: " + expensiveOperation ());
So how do we implement this method from within our Logger class? From the library point
of view, we can just use the builtin Supplier functional interface, which has a single get
method. We can then call isDebugEnabled in order to find out whether to call this method
and pass the result into our debug method if it is enabled. The resulting code is shown in
Example 4-3 .
Example 4-3. The implementation of a lambda-enabled logger
public
public void
void debug ( Supplier < String > message ) {
iif ( isDebugEnabled ()) {
debug ( message . get ());
}
}
Calling the get() method in this example corresponds to calling the lambda expression that
was passed into the method to be called. This approach also conveniently works with an-
onymous inner classes, which allows you maintain a backward-compatible API if you have
consumers of your code who can't upgrade to Java 8 yet.
It's important to remember that each of the different functional interfaces can have a different
name for its actual method. So, if we were using a Predicate , we would have to call test ,
or if we were using Function , we would have to call apply .
Primitives
You might have noticed in the previous section that we skimmed over the use of primitive
types. In Java we have a set of parallel types—for example, int and Integer —where one is
Search WWH ::




Custom Search