2. Introduction
Present a simple explanation and examples of new features on the Java 7 and 8;
The presentation mentions only the new features that the team judged more
relevant for the context of the Tools project;
A complete list of the new features can be found in the links below:
Java 7 New Features
Java 8 New Features
4. Underscore Between Literals
● Enables separate groups of digits in numeric literals, which can improve the
readability of the code;
● Valid statements:
○ Underscores are allowed only between digits.
int mask = 0b1010_1010_1010;
long big = 9_223_783_036_967_937L;
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BFFE;
5. Underscore Between Literals
● Invalid statements:
○ At the beginning or end of a number;
○ Adjacent to a decimal point in a floating point literal;
○ Prior to an F or L suffix;
○ In positions where a string of digits is expected.
int x1 = _52; int x1 = 52_;
float pi1 = 3_.1415F; float pi2 = 3._1415F;
long ssn = 999_99_L; float rad = 1_213_F;
int x2 = 0_x52; int x2 = 0x_52;
6. Strings in Switch
● Improves the readability of the code and generally more efficient byte codes than
an if-then-else statement;
● Before Java 7:
if (month.equals(“April”) || month.equals(“June”) ||
month.equals(“September”) || month.equals(“November”)) {
return 30;
} else if (month.equals(“January”) || month.equals(“March”) ||
month.equals(“May”) || month.equals(“July”) ||
month.equals(“August”) || month.equals(“December”)) {
Return 31;
} else if (month.equals(“February”)) {
...
}
7. Strings in Switch
● Improves the readability of the code and generally more efficient byte codes than
an if-then-else statement;
● Java 7 (String comparison is case sensitive):
switch(month) {
case “April”: case “June”:
case “September”: case “November”:
return 30;
case “January”: case “March”: case “May”:
case “July”: case “August”: case “December”:
return 31;
case “February”:
...
}
8. Diamond Operator
Reduces the Java verbosity surrounding generics by having the compiler infer
parameter types for constructors of generic classes;
Before Java 7:
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
Java 7:
Map<String, List<String>> myMap = new HashMap<>();
The following statements still generate raw type warning:
Map<String, List<String>> myMap = new HashMap();
Map myMap = new HashMap<String, List<String>>();
9. Multi-Catch
● Enables to catch multiple exceptions in the same catch block, which facilitates
easier and more concise exception handling;
● Before Java 7:
try {
// execute code that may throw exceptions
} catch(SQLException e) {
logger.log(e);
} catch(IOException e) {
logger.log(e);
}
10. Multi-Catch
● Enables to catch multiple exceptions in the same catch block, which facilitates
easier and more concise exception handling;
● Java 7:
try {
// execute code that may throw exceptions
} catch(SQLException | IOException e) {
logger.log(e);
}
11. Rethrow Exceptions
● Enables throwing more precise exceptions;
● Before Java 7:
public void loadFileToDb(File file) throws IOException, SQLException {
try {
// execute code that may throw exceptions
} catch(SQLException e) {
logger.log(e);
throw e;
} catch(IOException e) {
logger.log(e);
throw e;
}
}
12. Rethrow Exceptions
● Enables throwing more precise exceptions;
● Java 7 (this code would not compile before):
public void loadFileToDb(File file) throws IOException, SQLException {
try {
// execute code that may throw exceptions
} catch(Exception e) {
logger.log(e);
throw e;
}
}
13. Try-with-resources
● Enables to auto close resources which implement the AutoCloseable interface;
● Before Java 7:
InputStream is = null;
try {
is = new FileInputStream(new File(“data.txt”)); // read file
} catch(IOException e) { // handle exception
} finally {
if (is != null) {
try {
is.close();
} catch(IOException) {
}
}
}
14. Try-with-resources
● Enables to auto close resources which implement the AutoCloseable interface;
● Java 7:
try(InputStream is = new FileInputStream(new File(“data.txt”))) {
// read file
} catch(IOException e) {
// handle exception
}
● The AutoClosable interface consists of just one method:
public void close() throws Exception;
15. Try-with-resources
● Enables to auto close resources which implement the AutoCloseable interface;
● Java 7:
try(InputStream in = new FileInputStream(...);
OutputStream out = new FileOutputStream(...)) {
// read file
} catch(IOException e) {
// handle exception
}
16. NIO.2
● Provides new classes to support I/O operations;
● Before Java 7, the java.io.File class was the mechanism used for file I/O;
● Four main new types:
○ Class java.nio.file.Paths
■ Exclusively static methods to return a Path by converting a string or URI.
○ Interface java.nio.file.Path
■ Used for objects that represent the location of a file in a file system.
○ Class java.nio.file.Files
■ Exclusively static methods to operate on files, directories and other types of files.
○ Class java.nio.file.FileSystem
■ A variety of methods for obtaining information about the file system.
17. NIO.2
Files helper class main features:
Copy
Move
Delete
Create File/Directory
Create Temp File/Directory
Create Links
Attributes – Modified/Owner/Permissions, etc.
Read/Write
18. NIO.2
Copy file before Java 7:
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(new File(...));
output = new FileOutputStream(new File(...));
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
} finally {
input.close();
output.close();
}
23. Lambda
Provides a clear and concise way to represent one method interface using an
expression;
The annotation @FunctionalInterface ensures the developer does not break the rule
accidentally;
Replace (mostly) the old verbose Anonymous Class Instantiation;
Syntax:
(int a, int b) -> {return a > b}
24. Lambda
Any Interface with exactly one method can be instantiated as Lambda (static and
default methods does not count);
Before Java 8:
Runnable r1 = new Runnable(){
@Override
public void run(){
System.out.println("I’m running!");
}
};
● Java 8 with Lambda:
Runnable r2 = () -> System.out.println("I’m running too!");
25. Lambda
Comparator before Java 8:
Collections.sort(list, new Comparator<Product>(){
@Override
public int compare(Product p1, Product p2){
return p1.getId().compareTo(p2.getId());
}
});
Java 8 with Lambda:
Collections.sort(list, (p1, p2) -> p1.getId().compareTo(p2.getId()));
26. Lambda
Together with Streams, improve the Collection libraries making it easier to iterate
through, filter and extract data.
List<String> list = Arrays.asList(“a”, “b”, “c”);
list.forEach(e -> System.out.println(e));
list.forEach(e -> {
System.out.print(e);
System.out.print(e + “ again”);
});
list.stream()
.filter(s -> s.equals(“b”))
.forEach(s -> System.out.println(s));
27. Lambda
The package java.util.function provides a set of functional interfaces:
Predicate: Accepts one argument T and return a boolean value.
Consumer: Accepts one argument T and returns no result.
Function: Accepts one argument T and return a result U.
Supplier: No argument and return an object of type T.
UnaryOperator: Similar to Function, but it produces a result of the same type as the input.
BinaryOperator: Similar to UnaryOperator, but it accepts two arguments of the same type.
Recommended links:
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html
28. Default Methods
● Enables to add new methods to interfaces without breaking the classes that
implements that interface;
● It is the most practical way to allow backwards compatibility.
interface InterfaceA {
default void print() {
System.out.println(“Hi from InterfaceA”);
}
static void staticPrint() {
System.out.println(“Static message”);
}
}
29. Default Methods
● Case where a class implements two interfaces with the same default method.
interface InterfaceA {
default void print() { ... }
}
interface InterfaceB {
default void print() { ... };
}
public class MyClass implements InterfaceA, InterfaceB {
@Override
public void print() {
InterfaceA.super.print();
}
}
30. Method References
● Enables to reference constructors or methods without executing them;
● It’s related and similar to Lambda expressions feature;
● Syntax:
Car car = Car.create( Car::new );
● There are four types of method reference:
○ Reference to a constructor;
○ Reference to a static method;
○ Reference to an instance method of an arbitrary object of a particular type;
○ Reference to an instance method of a particular object;
31. Method References
● Reference to a constructor:
public class Factory {
public static Product create(String name, Supplier<Product> supplier) {
Product p = supplier.get();
p.setName(name);
return p;
}
public static void main(String... args) {
Factory.create("Car", Product::new);
Factory.create("Car", () -> new Product()); // Lambda
form
}
}
32. Method References
● Reference to a static method:
public class Calculator {
public static int sum(int a, int b) {
return a + b;
}
public static void execute(int a, int b, BinaryOperator<Integer> op) {
System.out.println(op.apply(a, b));
}
public static void main(String... args) {
Calculator.execute(1, 2, Calculator::sum);
Calculator.execute(1, 2, (a, b) -> a + b); // Lambda
form
}
33. Method References
● Reference to an instance method of an arbitrary object of a particular type:
public class Product {
public static double avegare(List<Product> list,
Function<Product, Integer> func) {
int sum = 0;
for (Product p : list) {
sum += func.apply(p);
}
return sum / list.size();
}
public static void main(String... args) {
Product.avegare(productList, Product::getPrice); //
Product::getSold
Product.avegare(productList, p -> p.getPrice()); // Lambda form
}
34. Method References
● Reference to an instance method of a particular object:
public static void print(List<Integer> list, Consumer<Integer> cons) {
list.forEach(x -> cons.accept(x));
}
public static void main(String... args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
MyClass.print(numbers, System.out::println);
MyClass.print(numbers, x -> System.out.println(x)); // Lambda form
}
35. Repeating Annotations
● Enables repeating annotations without the need of a container annotations;
● Before Java 8:
@Manufactures({
@Manufacturer(name = “BMW”),
@Manufacturer(name = “Range Rover”)
})
public class Car { ... }
● Java 8:
@Manufacturer(name = “BMW”),
@Manufacturer(name = “Range Rover”)
public class Car { ... }
36. Type Annotations
● Enables annotations to be applied to any type use, i.e., annotations can be used
anywhere you use a type;
● Java 8 does not provide any type checking framework;
● Some examples:
@NotNull String str1 = ...
@Email String str2 = ...
@NotNull @NotBlank String str3 = ...
new @NonEmpty @Readonly List<String>(myNonEmptyStringSet)
myString = (@NonNull String) myObject;
List<@Email String> emails = ...
Map<@NonNull String, @NonEmpty List<@Readonly Document>> documents;
38. Optional
● New type that provides a container that may contain some value or may contain a
non-null value and it is primarily intended for use in streams;
● Helps alleviate NullPointerException;
● Static methods used as Optional factory:
○ Optional.of(T)
■ Returns an Optional with the given non-null value.
○ Optional.ofNullable(T)
■ Returns an Optional if given value is non-null, otherwise returns empty Optional.
○ Optional.empty(T)
■ Returns an empty Optional.
39. Optional
● Main Optional methods:
○ T get()
■ Returns value if present, otherwise throws NoSuchElementException.
○ boolean isPresent()
■ Returns true if there is value present, otherwise false.
○ T orElse(T)
■ Returns the value if present, otherwise returns the given value.
○ Optional<T> filter(Predicate<T>)
■ Returns an Optional with the value if the value matches the given predicate, otherwise
returns an empty Optional.
○ Optional<U> map(Function<T, U>)
■ Apply the provided mapping function and returns an Optional with the new value, if result is
non-null, otherwise returns an empty Optional.
40. Date/Time API
● New Date/Time API on java.time package;
● Contains classes to represents the principle date-time concepts, including
instants, durations, dates, times, time-zones and periods;
● All the classes are immutable and thread-safe.
41. Date/Time API
Instant: Represents numeric timestamp. Equivalent to java.util.Date.
Instant.now()
// 2016-06-12T23:22:53.320Z
Instant.now().plusSeconds(60) // 2016-06-
12T23:23:53.320Z
LocalDate: Represents a date (year-month-day).
LocalDate.now()
LocalDate.of(2000, Month.NOVEMBER, 20) // 2000-11-20
LocalTime: Represents only time.
LocalTime.now()
// 18:59:07.203
LocalTime.now().minusMinutes(30)
LocalDateTime: Represents both date and time, without a time zone.
42. Date/Time API
YearMonth: Represents the month of a specific year.
YearMonth.of(2012, Month.FEBRUARY).lengthOfMonth() // 29
YearMonth.now().plusMonths(12)
// 2017-06
MonthDay: Represents the day of a particular month.
MonthDay.of(Month.FEBRUARY, 29).isValidYear(2010) // false
MonthDay.of(Month.DECEMBER, 5).withDayOfMonth(31) // --12-31
Year: Represents a year.
Year.of(2012).isLeap()
// true
Year.of(2016).atDay(200)
// 2016-07-18
43. Date/Time API
ZonedDateTime: Represents a date and time with a time zone.
ZoneOffset: Represents a time zone offset.
OffsetTime: Represents a time and offset without a date.
LocalDateTime leaving = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
// leaving = 2013-07-20T19:30
ZoneId leavingZone = ZoneId.of("America/Los_Angeles");
ZonedDateTime departure = ZonedDateTime.of(leaving, leavingZone);
// departure = 2013-07-20T19:30-07:00[America/Los_Angeles]
ZoneOffset offset = departure.getOffset(); // -07:00
OffsetTime offsetTime = OffsetTime.from(departure) // 19:30-07:00
44. Date/Time API
● Duration: Represents a simple measure of time along the time-line in
nanoseconds.
Instant start = Instant.now();
Duration gap = Duration.ofSeconds(10);
Instant later = start.plus(gap);
● Period: Represents an amount of time in units meaningful to humans, such as
years or days.
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
Period p = Period.between(birthday, today);
p.getYears() / p.getMonths() / p.getDays() // 56 / 4 / 29
45. Date/Time API
TemporalAdjusters: Provides common and useful method for temporal adjustment.
date.with(TemporalAdjusters.firstDayOfMonth());
date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
date.with(TemporalAdjusters.lastDayOfYear());
date.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.TUESDAY));
date.with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
date.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
DateTimeFormatter: Formatter for printing and parsing date-time objects.
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
String text = date.format(formatter);
LocalDate parsedDate = LocalDate.parse(text, formatter);
46. Date/Time API
● The main API is based around the calendar system defined in ISO-8601.
● The package java.time.chrono provides basic support for other calendar systems.
○ Hijrah calendar
○ Japanese calendar
○ Minguo calendar
○ Thai Buddhist calendar
Chronology chrono = ThaiBuddhistChronology.INSTANCE;
ChronoLocalDate nowThai = chrono.dateNow();
chrono.getId(); // ThaiBuddhist
nowThai.toString(); // ThaiBuddhist BE 2559-06-12
47. Base64
● New API for Base64 encoding and decoding has been introduced in the java.util
package;
● The Base64 class defines factory methods to get Encoder and Decoder instances:
String str = “exampleString”;
Base64.Encoder enc = Base64.getEncoder();
byte[] strenc = enc.encode(str.getBytes(“UTF-8”));
Base64.Decoder dec = Base64.getDecoder();
byte[] strdec = dec.decode(strenc);
48. Maps
● New and useful methods for doing common tasks.
map.putIfAbsent(2, “Two”);
map.forEach((key, val) -> System.out.println(val));
// Remapping
map.computeIfPresent(3, (key, val) -> “Number” + key); // Number3
map.computeIfAbsent(10, key -> "Ten”); //
Add {10=“Ten”}
map.merge(5, “New”, (val, newVal) -> newVal +“-”+ val); // Set {5=“New-Five”}
map.remove(4, "Six"); // false
map.remove(4, "Four"); // true
map.getOrDefault(100, "Not found"); // Not found
49. Streams
● New Package java.util.stream introduces real-world functional-style
programming into the Java;
● Makes collections processing greatly simplified, but it is not limited to Java
collections only.
● Recommended links:
○ https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
○ http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/
50. Streams
● Stream pipeline are composed by:
○ Source: might be an array, a collection, a generator function, an I/O channel, etc.
○ Intermediate operations: transform a stream into another stream.
○ Terminal operation: produces a result or side-effect.
● Syntax:
int sum = widgets.stream()
.filter(b -> b.getColor() == RED)
.mapToInt(b -> b.getWeight())
.sum();
51. Streams
● Main streams sources:
○ Collections: stream() and parallelStream() methods.
○ Arrays: Arrays.stream(Object[]).
○ Static factory methods: Stream.of(Object[]), IntStream.range(int, int) or Stream.iterate(Object,
UnaryOperator).
○ Lines of a file: BufferedReader.lines().
○ Random numbers: Random.ints().
○ Other methods: BitSet.stream(), Pattern.splitAsStream(CharSequence), JarFile.stream(), etc.
52. ● Main intermediate stream operations:
○ distinct(): eliminate duplicated elements (according to equals).
○ filter(Predicate): filter the elements that match the given predicate.
○ limit(long): truncate the stream keeping only n elements.
○ skip(long): discard the first n elements of the stream.
○ sorted()/sorted(Comparator): sorts the elements according to the natural order or to a
Comparator
○ map(Function)/MapToDouble/MapToInt/MapToLong: applies the given function to the
elements of the stream.
○ peek(Consumer): performs the provided action on each element.
Streams
53. Streams
● Main final steam operations:
○ allMatch(Predicate)/anyMatch/noneMatch: returns true if all elements/any element/no
element of the stream match the provided predicate.
○ count(): returns the number of elements in the stream as long.
○ findFirst(): returns an Optional with the first element of the stream.
○ max(Comparator)/min(Comparator): returns the maximum/minimum element of the stream
according to the provided Comparator.
○ max()/min()/average(): returns the maximum element/minimum element/average of the
elements of the stream. Available in IntStream, DoubleStream and LongStream.
○ forEach(Consumer): performs an action for each element of this stream.
57. Nashorn JavaScript Engine
Allows better interoperability between JavaScript and Java;
Creating the engine?
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Execute javascript using the eval method
engine.eval("print('Hello World!');");
You can also pass a FileReader:
engine.eval(new FileReader("script.js"));
58. Nashorn JavaScript Engine
You can invoke JavaScript functions from Java, using the invocable API:
// JavaScript code
var fun1 = function(name) {
print('Hi there from Javascript, ' + name);
return "greetings from javascript";
};
// Java code
engine.eval(new FileReader("script.js"));
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("fun1", "Peter Parker");
59. Nashorn JavaScript Engine
And you can also call Java code from the Javascript:
// Java code
static String fun1(String name) {
System.out.format("Hi there from Java, %s", name);
return "greetings from java";
}
// JavaScript code
var MyJavaClass = Java.type('my.package.MyJavaClass');
var result = MyJavaClass.fun1('John Doe');
print(result);
If a catch block handles more than one exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.
If an exception is thrown in the try block and another Exception is thrown while closing the resource, the first Exception is the one eventually thrown to the caller. The second Exception is available to the caller via the ex.getSupressed() method.
Old single method interfaces: Comparator (compare), Runnable (run).