Table of Contents
10.1 Local-Variable Type Inference
var i = 10;
var hello = "Hello world!";
var list = List.of(1, 2, 3, 4, 5);
var httpClient = HttpClient.newBuilder().build();
var status = getStatus();
Code language: Java (java)
int i = 10;
String hello = "Hello world!";
List<Integer> list = List.of(1, 2, 3, 4, 5);
HttpClient httpClient = HttpClient.newBuilder().build();
Status status = getStatus();
Code language: Java (java)
10.2 Immutable/Unmodifiable Collections
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<Integer> unmodifiable = Collections.unmodifiableList(list);
Code language: Java (java)
unmodifiable.add(4);
⟶
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableCollection.add(...)
at ...
Code language: Java (java)
list.add(4);
System.out.println("unmodifiable = " + unmodifiable);
⟶
unmodifiable = [1, 2, 3, 4]
Code language: Java (java)
List.copyOf(), Set.copyOf(), and Map.copyOf()
List<Integer> immutable = List.copyOf(list);
list.add(4);
System.out.println("immutable = " + immutable);
⟶
immutable = [1, 2, 3]
Code language: Java (java)
immutable.add(4);
⟶
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(...)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(...)
at ...
Code language: Java (java)
List<Integer> copy = new ArrayList<>(list);
Code language: Java (java)
Collectors.toUnmodifiableList(), toUnmodifiableSet(), and toUnmodifiableMap()
List<Integer> list = IntStream.rangeClosed(1, 3).boxed().collect(Collectors.toList());
Set<Integer> set = IntStream.rangeClosed(1, 3).boxed().collect(Collectors.toSet());
Map<Integer, String> map = IntStream.rangeClosed(1, 3).boxed()
.collect(Collectors.toMap(Function.identity(), String::valueOf));
list.add(4);
set.add(4);
map.put(4, "4");
System.out.println("list = " + list);
System.out.println("set = " + set);
System.out.println("map = " + map);
Code language: Java (java)
Code language: plaintext (plaintext)list = [1, 2, 3, 4] set = [1, 2, 3, 4] map = {1=1, 2=2, 3=3, 4=4}
List<Integer> list =
IntStream.rangeClosed(1, 3).boxed().collect(Collectors.toUnmodifiableList());
Set<Integer> set =
IntStream.rangeClosed(1, 3).boxed().collect(Collectors.toUnmodifiableSet());
Map<Integer, String> map =
IntStream.rangeClosed(1, 3)
.boxed()
.collect(Collectors.toUnmodifiableMap(Function.identity(), String::valueOf));
Code language: Java (java)
10.3 Optional.orElseThrow()
Optional<String> result = getResult();
if (result.isPresent()) {
System.out.println(result.get());
}
Code language: Java (java)
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
10.4 Time-Based Release Versioning
java.util.Optional, java.util.OptionalDouble, java.util.OptionalIntand java.util.OptionalLongeach got a new method orElseThrow()which doesn't take any argument and throws NoSuchElementExceptionif no value is present:
@Test public void whenListContainsInteger_OrElseThrowReturnsInteger() { Integer firstEven = someIntList.stream() .filter(i -> i % 2 == 0) .findFirst() .orElseThrow(); is(firstEven).equals(Integer.valueOf(2)); }
It's synonymous with and is now the preferred alternative to the existing get()method.
10.5 Performance Improvement
This has been changed to the parallel mark-sweep-compact algorithm in Java 10 effectively reducing the stop-the-world time during full GC.
10.5.2 Application Class-Data SharinClass-Data Sharing
introduced in JDK 5, allows a set of classes to be pre-processed into a shared archive file that can then be memory-mapped at runtime to reduce startup time which can also reduce dynamic memory footprint when multiple JVMs share the same archive file.
CDS only allowed the bootstrap class loader, limiting the feature to system classes only. Application CDS (AppCDS) extends CDS to allow the built-in system class loader (a.k.a., the “app class loader”), the built-in platform class loader, and custom class loaders to load archived classes. This makes it possible to use the feature for application classes.
We can use the following steps to make use of this feature:
1. Get the list of classes to archive
The following command will dump the classes loaded by the HelloWorld application into hello.lst:
$ java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst \
-cp hello.jar HelloWorld
2. Create the AppCDS archive
Following command creates hello.js a using the hello.lst as input:
$ java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst \
-XX:SharedArchiveFile=hello.jsa -cp hello.jar
3. Use the AppCDS archive
Following command starts the HelloWorld application with hello.jsa as input:
$ java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa \
-cp hello.jar HelloWorld
AppCDS was a commercial feature in Oracle JDK for JDK 8 and JDK 9. Now it is open sourced and made publicly available.
10.5.4. Experimental Java-Based JIT Compiler
Graal is a dynamic compiler written in Java that integrates with the HotSpot JVM; it's focused on high performance and extensibility. It's also the basis of the experimental Ahead-of-Time (AOT) compiler introduced in JDK 9.
JDK 10 enables the Graal compiler, to be used as an experimental JIT compiler on the Linux/x64 platform.
To enable Graal as the JIT compiler, use the following options on the java command line:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
Note that this is an experimental feature and we may not necessarily get better performance than the existing JIT compilers.
10.6 Other Changes in Java 10
10.6.1 Heap Allocation on Alternative Memory Devices
Additional Unicode Language-Tag Extensions
Key | Description | Examples |
---|---|---|
cu | Currency | ISO 4217 currency codes |
fw | First day of week | sun (Sunday), mon (Monday) |
rg | Region override | uszzzz (US units) |
tz | Timezone | uslax (Los Angeles), deber (Berlin) |
Key | Description | Examples |
---|---|---|
ca | Calendar | gregorian, buddhist, chinese |
nu | Numbering system | arab, roman |
Locale locale = Locale.forLanguageTag("de-DE-u-cu-usd-fw-wed-tz-uslax");
Currency currency = Currency.getInstance(locale);
Calendar calendar = Calendar.getInstance(locale);
DayOfWeek firstDayOfWeek = DayOfWeek.of((calendar.getFirstDayOfWeek() + 5) % 7 + 1);
DateFormat dateFormat = DateFormat.getTimeInstance(LONG, locale);
String time = dateFormat.format(new Date());
System.out.println("currency = " + currency);
System.out.println("firstDayOfWeek = " + firstDayOfWeek);
System.out.println("time = " + time);
Code language: Java (java)
Code language: plaintext (plaintext)currency = USD firstDayOfWeek = WEDNESDAY time = 11:45:50 PDT
Code language: plaintext (plaintext)currency = EUR firstDayOfWeek = MONDAY time = 20:46:30 MESZ